using Microsoft.VisualStudio.TestTools.UnitTesting; using Dfs.WayneChina.HengshanPayTerminal; using Dfs.WayneChina.HengshanPayTerminal.MessageEntity.Incoming; using System; using System.Collections.Generic; using System.Linq; using Dfs.WayneChina.HengshanPayTerminal.MessageEntity.Outgoing; using Dfs.WayneChina.HengshanPayTerminal.MessageEntity; namespace HengshanPayTerminal_Test { [TestClass] public class HengshanICProtocolMessagesTests { #region Parser instance Dfs.WayneChina.HengshanPayTerminal.Parser parser = new Dfs.WayneChina.HengshanPayTerminal.Parser(); #endregion #region Incoming raw messages in bytes byte[] checkCmdReqBytes = new byte[] { 0xFA, 0x01, 0x01, 0x55, 0x00, 0x12, 0x10, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00, 0x04, 0x40, 0x00, 0x01, 0xD0, 0x09, 0x29, 0xFF, 0x09, 0x67 }; byte[] registerReqBytes = new byte[] { 0xFA, 0x01, 0x01, 0x01, 0x00, 0x05, 0x13, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x0A, 0x08 }; byte[] validateCardReqBytes = new byte[] { 0xFA, 0x01, 0x01, 0x67, 0x00, 0x1C, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x05, 0x28, 0xFD, 0xC6, 0x93, 0x06, 0x01, 0x01, 0x01, 0x04, 0xE2, 0x03, 0xFB, 0x41, 0xF0, 0xFF, 0x24, 0x05 }; byte[] authReqBytes = new byte[] { 0xFA, 0x01, 0x01, 0x6A, 0x00, 0x2B, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x05, 0x28, 0x0F, 0x41, 0xDC, 0x00, 0x00, 0x00, 0x20, 0x19, 0x03, 0x12, 0x08, 0x42, 0x26, 0x00, 0x00, 0x03, 0x0A, 0x06, 0x0E, 0x50, 0x01, 0x01, 0x10, 0x31, 0x01, 0x04, 0xE3, 0x67, 0xFF, 0x1C, 0x01 }; byte[] fuelDataReqBytes = new byte[] { 0xFA, 0x01, 0x01, 0x74, 0x00, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x0A, 0x06, 0x0F, 0x01, 0x01, 0x10, 0x31, 0x00, 0x20, 0x33, 0x00, 0x04, 0xFA, 0x02, 0x87, 0x20, 0x19, 0x03, 0x12, 0x08, 0x42, 0x26, 0x20, 0x19, 0x03, 0x12, 0x08, 0x42, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x05, 0x28, 0x01, 0x04, 0xE3, 0x00, 0x46, 0xA3, 0x7A, 0xFF, 0x18, 0x38 }; byte[] paymentReq = new byte[] { 0xFA, 0x01, 0x01, 0x75, 0x00, 0x22, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x05, 0x28, 0x20, 0x19, 0x03, 0x12, 0x08, 0x42, 0x26, 0x00, 0x00, 0x03, 0x0A, 0x06, 0x0F, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x75, 0x60 }; byte[] trxDataReqBytes1 = new byte[] { 0xFA, 0x01, 0x01, 0x76, 0x00, 0x80, 0x2D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x0A, 0x06, 0x0F, 0x00, 0x20, 0x19, 0x03, 0x12, 0x08, 0x42, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x05, 0x28, 0x03, 0xFB, 0x21, 0xBD, 0x00, 0x20, 0x33, 0x00, 0x20, 0x33, 0x67, 0x00, 0x00, 0x01, 0x04, 0xE3, 0x01, 0x01, 0x02, 0x87, 0x10, 0x31, 0x00, 0x04, 0xFA, 0x00, 0x46, 0xA3, 0x7A, 0x20, 0x19, 0x03, 0x12, 0x08, 0x42, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x6D, 0x79 }; byte[] changeAuthModeBytes = new byte[] { 0xFA, 0x01, 0x01, 0x73, 0x00, 0x04, 0x1B, 0x01, 0x01, 0x02, 0xFF, 0x3E, 0x25 }; byte[] changeAuthModeAckBytes = new byte[] { 0xFA, 0x01, 0x01, 0x74, 0x00, 0x05, 0x20, 0x01, 0x01, 0x01, 0x01, 0xFF, 0x39, 0x1A }; byte[] lockPumpResult = new byte[] { 0xFA, 0x01, 0x01, 0x0E, 0x00, 0x09, 0x45, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0xFF, 0x36, 0x18 }; byte[] fullTotalizerBytes = new byte[] { 0xFA, 0x01, 0x01, 0x28, 0x00, 0x0B, 0x49, 0x01, 0x01, 0x01, 0xEE, 0xBD, 0xBD, 0x0C, 0x55, 0x37, 0x82, 0xFF, 0x1E, 0x16 }; byte[] cancelAuthRequestBytes = new byte[] { 0xFA, 0x03, 0x03, 0x35, 0x00, 0x23, 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x05, 0x43, 0x20, 0x19, 0x12, 0x12, 0x12, 0x22, 0x46, 0x00, 0x00, 0x2F, 0x77, 0x00, 0x00, 0x50, 0x03, 0x03, 0x01, 0x3E, 0x05, 0x67, 0xFF, 0x6A, 0x7B }; byte[] queryGrayRecordReqBytes = new byte[] { 0xfa, 0x04, 0x04, 0x1d, 0x00, 0x18, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x03, 0x83, 0x00, 0x00, 0x19, 0xe9, 0x00, 0x04, 0x20, 0x19, 0x11, 0x19, 0x17, 0x07, 0x15, 0xff, 0x09, 0x38 }; byte[] trxDataReqBytes = new byte[] { 0xFA,0x03,0x03,0x1C,0x00,0x80,0x2D,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x37,0x00, 0x00,0x00,0x20,0x20,0x03,0x25,0x10,0x54,0x42,0x11,0x00,0x01,0x10,0x00,0x13,0x80, 0x00,0x10,0x51,0x00,0x01,0x77,0xE6,0x00,0x01,0xEE,0x00,0x01,0xB2,0x64,0x00,0x00, 0x01,0x00,0x05,0x03,0x03,0x02,0xA5,0x10,0x21,0x00,0x00,0x49,0x00,0x00,0x17,0x12, 0x20,0x20,0x03,0x25,0x10,0x55,0x09,0x11,0x00,0x10,0x19,0x90,0x10,0x00,0x00,0x30, 0x87,0x6F,0xAA,0xDF,0x2F,0x20,0x20,0x03,0x05,0x10,0x05,0x00,0x00,0x00,0x40,0x5C, 0x39,0x33,0xCA,0x04,0x7F,0x97,0xF9,0x1A,0xF3,0x8C,0x48,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x2D,0x62 }; byte[] incompleteCheckCmdBytes = new byte[] { 0xFA, 0x02, 0x02, 0x12, 0xFA, 0x01, 0x01, 0x24, 0x00, 0x1C, 0x10, 0x00, 0x00, 0x00, 0x49, 0x31, 0x31, 0x01, 0x03, 0x00, 0x00, 0x07, 0x08, 0x00, 0x01, 0x5C, 0x02, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x54, 0x49 }; #endregion /**************************************************************************/ /****************************** FEED TESTS ******************************/ /**************************************************************************/ [TestMethod()] public void Incomplete_feed_is_processed() { List result = null; var stateMachine = new StateMachineMessageCutter(); stateMachine.OnMessageCut += (r, _) => { result = stateMachine.Message.ToList(); }; bool invalidMessageCutCalled = false; stateMachine.OnInvalidMessageRead += (__, ___) => invalidMessageCutCalled = true; stateMachine.Feed(incompleteCheckCmdBytes); Assert.AreEqual(true, result != null); Assert.AreEqual(true, invalidMessageCutCalled != true); Assert.AreEqual(true, result.Any()); Assert.AreEqual(true, result[0] == 0xFA); } /**************************************************************************/ /************************ DE-SERIALIZATION TESTS ************************/ /**************************************************************************/ #region Deserialization tests /*************************** Check Cmd Request ****************************/ #region Check Cmd request [TestMethod] public void Check_cmd_could_be_parsed_Ok() { var msg = parser.Deserialize(checkCmdReqBytes) as CheckCmdRequest; Assert.IsNotNull(msg); Assert.AreEqual(msg.DispenserState, 3); Assert.AreEqual(msg.Price, 2345); } #endregion /**************************** Register Request ****************************/ #region Register request [TestMethod] public void RegisterRequest_could_be_parsed_Ok() { var msg = parser.Deserialize(registerReqBytes) as RegisterRequest; Assert.IsNotNull(msg); Assert.AreEqual("00000001", msg.TerminalId); //Only one field `Terminal ID` exists for this request. } #endregion /************************** Change Auth Mode Ack **************************/ #region Change Auth Mode Ack [TestMethod] public void ChangeAuthModeAck_could_be_parsed_Ok() { var msg = parser.Deserialize(changeAuthModeAckBytes) as ChangeAuthModeAck; Assert.IsNotNull(msg); Assert.AreEqual(msg.ModeChangeResult, 1); //result 1, failure } #endregion /**************************** Lock Unlock Ack *****************************/ #region Lock pump [TestMethod] public void LockPumpResponse_could_be_parsed_Ok() { var msg = parser.Deserialize(lockPumpResult) as LockOrUnlockPumpAck; Assert.IsNotNull(msg); Assert.AreEqual(msg.DispenserState, DispenserState.Closed); //dispenser state 2, closed } #endregion /************************* Validate Card Request ***************************/ #region Validate card [TestMethod] public void ValidateCardRequest_could_be_parsed_Ok() { var msg = parser.Deserialize(validateCardReqBytes) as ValidateCardRequest; Assert.IsNotNull(msg); Assert.IsTrue(msg.Asn.Contains("10010528")); } [TestMethod] public void ValidateCardRequest_terminalId_is_Ok() { var msg = parser.Deserialize(validateCardReqBytes) as ValidateCardRequest; Assert.AreEqual("00000001", msg.TerminalID); } [TestMethod] public void ValidateCardRequest_physicalCardNo_is_Ok() { var msg = parser.Deserialize(validateCardReqBytes) as ValidateCardRequest; Assert.AreEqual(110348029, int.Parse(msg.PhysicalCardNo, System.Globalization.NumberStyles.HexNumber)); //"FDC69306" } [TestMethod] public void ValidateCardRequest_cardInfo_is_Ok() { var msg = parser.Deserialize(validateCardReqBytes) as ValidateCardRequest; Assert.AreEqual(1, msg.CurrentCardInfo.CardType); Assert.AreEqual(0x4E2, msg.CurrentCardInfo.CardCtc); } [TestMethod] public void ValidateCardRequest_balance_is_Ok() { var msg = parser.Deserialize(validateCardReqBytes) as ValidateCardRequest; Assert.AreEqual(66798064, msg.Balance); } #endregion /***************************** Auth Request ********************************/ #region Auth request [TestMethod] public void AuthRequest_could_be_parsed_Ok() { var msg = parser.Deserialize(authReqBytes) as AuthRequest; Assert.IsNotNull(msg); Assert.IsTrue(msg.Asn.Contains("10010528")); Assert.AreEqual(msg.MaxAmount, 0xF41DC); } [TestMethod] public void AuthRequest_FPCode_is_Ok() { var msg = parser.Deserialize(authReqBytes) as AuthRequest; Assert.IsNotNull(msg); Assert.AreEqual(1, msg.FuelingPoint.NozzleNo); Assert.AreEqual(1, msg.FuelingPoint.PumpNo); } [TestMethod] public void AuthRequest_cardCtc_is_Ok() { var msg = parser.Deserialize(authReqBytes) as AuthRequest; Assert.IsNotNull(msg); Assert.AreEqual(msg.CurrentCardInfo.CardCtc, 0x4E3); } [TestMethod] public void AuthRequest_maxAllowedAmount_is_Ok() { var msg = parser.Deserialize(authReqBytes) as AuthRequest; Assert.IsNotNull(msg); Assert.AreEqual(msg.MaxAmount, 0xF41DC); } #endregion /***************************Cancel Auth Request ****************************/ #region Cancel auth [TestMethod] public void CancelAuthRequest_can_be_parsed_Ok() { var msg = parser.Deserialize(cancelAuthRequestBytes) as CancelAuthRequest; Assert.IsNotNull(msg); Assert.IsTrue(msg.Asn.Contains("10010543")); } [TestMethod] public void CancelAuthRequest_posttc_is_ok() { var msg = parser.Deserialize(cancelAuthRequestBytes) as CancelAuthRequest; Assert.IsNotNull(msg); Assert.AreEqual(0x2F77, msg.PosTtc); } #endregion /************************ Fueling Data Request ****************************/ #region FuelingDataRequest [TestMethod] public void FuelDataRequest_terminalId_is_Ok() { var msg = parser.Deserialize(fuelDataReqBytes) as FuelingDataRequest; Assert.IsNotNull(msg); Assert.AreEqual("00000001", msg.TerminalId); } [TestMethod] public void FuelingDataRequest_PosTtc_is_Ok() { var msg = parser.Deserialize(fuelDataReqBytes) as FuelingDataRequest; Assert.IsNotNull(msg); Assert.AreEqual(msg.PosTtc, 0x30A); } [TestMethod] public void FuelingDataRequest_SeqNo_is_Ok() { var msg = parser.Deserialize(fuelDataReqBytes) as FuelingDataRequest; Assert.IsNotNull(msg); Assert.AreEqual(0x60F, msg.SeqNo); } [TestMethod] public void FuelDataRequest_productCode_is_Ok() { var msg = parser.Deserialize(fuelDataReqBytes) as FuelingDataRequest; Assert.IsNotNull(msg); Assert.AreEqual(1031, msg.ProductCode); } [TestMethod] public void FuelDataRequest_amount_is_Ok () { var msg = parser.Deserialize(fuelDataReqBytes) as FuelingDataRequest; Assert.IsNotNull(msg); Assert.AreEqual(0x2033, msg.Amount); } [TestMethod] public void FuelingDataRequest_volume_is_Ok() { var msg = parser.Deserialize(fuelDataReqBytes) as FuelingDataRequest; Assert.IsNotNull(msg); Assert.AreEqual(0x4FA, msg.Volume); } [TestMethod] public void FuelingDataRequest_price_is_Ok() { var msg = parser.Deserialize(fuelDataReqBytes) as FuelingDataRequest; Assert.IsNotNull(msg); Assert.AreEqual(0x287, msg.Price); } [TestMethod] public void FuelDataRequest_cardNo_is_Ok() { var msg = parser.Deserialize(fuelDataReqBytes) as FuelingDataRequest; Assert.IsNotNull(msg); Assert.IsTrue(msg.Asn.Contains("10010528")); } [TestMethod] public void FuelingDataRequest_cardType_is_Ok() { var msg = parser.Deserialize(fuelDataReqBytes) as FuelingDataRequest; Assert.IsNotNull(msg); Assert.AreEqual(1, msg.CurrentCardInfo.CardType); } [TestMethod] public void FuelingDataRequest_cardCtc_is_Ok() { var msg = parser.Deserialize(fuelDataReqBytes) as FuelingDataRequest; Assert.IsNotNull(msg); Assert.AreEqual(0x4E3, msg.CurrentCardInfo.CardCtc); } #endregion /***************************** Payment Request ****************************/ #region Payment request tests [TestMethod] public void PaymentRequest_terminalId_is_Ok() { var msg = parser.Deserialize(paymentReq) as PaymentRequest; Assert.AreEqual("00000001", msg.TerminalId); } [TestMethod] public void PaymentRequest_cardNo_is_parsed_Ok() { var msg = parser.Deserialize(paymentReq) as PaymentRequest; Assert.IsNotNull(msg); Assert.AreEqual("10010528", msg.Asn.TrimStart('0')); } [TestMethod] public void PaymentRequest_authTime_is_Ok() { var msg = parser.Deserialize(paymentReq) as PaymentRequest; Assert.AreEqual("20190312084226", msg.AuthTime); } [TestMethod] public void PaymentRequest_posTtc_is_Ok() { var msg = parser.Deserialize(paymentReq) as PaymentRequest; Assert.AreEqual(0x30A, msg.PosTtc); } [TestMethod] public void PaymentRequest_seqNo_is_Ok() { var msg = parser.Deserialize(paymentReq) as PaymentRequest; Assert.AreEqual(1551, msg.SeqNo); //0x60F } [TestMethod] public void PaymentRequest_fuelingPoint_is_Ok() { var msg = parser.Deserialize(paymentReq) as PaymentRequest; Assert.AreEqual(1, msg.FuelingPoint.PumpNo); Assert.AreEqual(1, msg.FuelingPoint.NozzleNo); } #endregion /********************** Transaction Data Request **************************/ #region TransactionData request tests [TestMethod] public void TransactionData_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.IsNotNull(msg); } [TestMethod] public void TransactionData_terminalId_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("00000003", msg.TerminalId); } [TestMethod] public void TransactionData_terminal_ttc_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(msg.DitTTC, 0x37); } [TestMethod] public void TransactionData_pump_filling_sequence_number_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(msg.SeqNo, 0); } [TestMethod] public void TransactionData_transaction_type_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(msg.TrxType, 0x00); } [TestMethod] public void TransactionData_card_number_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("11000110001380001051", msg.Asn.TrimStart('0')); } [TestMethod] public void TransactionData_card_balance_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(msg.CardBalance, 0x177E6); } [TestMethod] public void TransactionData_filling_amount_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(msg.FillingAmount, 0x1EE); } [TestMethod] public void TransactionData_pay_amount_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(0x1B2, msg.PaymentAmount); } [TestMethod] public void TransactionData_pay_x_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(msg.PaymentMethodLocation, 0x64); } [TestMethod] public void TransactionData_discountNo_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(0, msg.DiscountNo); } [TestMethod] public void TransactionData_cardInfo_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(1, msg.CurrentCardInfo.CardType); Assert.AreEqual(5, msg.CurrentCardInfo.CardCtc); } [TestMethod] public void TransactionData_price_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(msg.Price, 0x2A5); } [TestMethod] public void TransactionData_product_code_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(1021, msg.ProductCode); } [TestMethod] public void TransactionData_volume_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(msg.Volume, 0x49); } [TestMethod] public void TransactionData_volume_total_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual(msg.VolumeTotal, 0x00001712); } [TestMethod] public void TransactionData_transaction_end_time_could_be_parsed_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("20200325105509", msg.TrxEndTime); } [TestMethod] public void TransactionData_psamAsn_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("11001019901000003087", msg.PsamAsn); } [TestMethod] public void TransactionData_PsamTac_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("6FAADF2F", msg.PsamTac); } [TestMethod] public void TransactionData_PsamTid_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("202003051005", msg.PsamTid); } [TestMethod] public void TransactionData_PsamTtc_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("00000040", msg.PsamTtc); } [TestMethod] public void TransactionData_tac_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("5C3933CA", msg.Tac); } [TestMethod] public void TransactionData_gMac_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("047F97F9", msg.Gmac); } [TestMethod] public void TransactionData_tMac_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("1AF38C48", msg.Tmac); } [TestMethod] public void TransactionData_lineCode_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("000000", msg.LineCode); } [TestMethod] public void TransactionData_carCode_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("000000", msg.CarCode); } [TestMethod] public void TransactionData_vehiclNo_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("00000000000000000000000000000000", msg.VehicleNo); } [TestMethod] public void TransactionData_loyaltyCardNo_is_Ok() { var msg = parser.Deserialize(trxDataReqBytes) as TransactionDataRequest; Assert.AreEqual("00000000", msg.LoyaltyCardNo); } #endregion /************************* Data Download Request **************************/ #region Data Download request [TestMethod] public void DataDownloadRequest_could_be_parsed_Ok() { var dataDownloadReq = new byte[] { 0xFA, 0x03, 0x03, 0x26, 0x00, 0x04, 0x25, 0x04, 0x00, 0x29, 0xFF, 0x64, 0x64 }; var msg = parser.Deserialize(dataDownloadReq) as DataDownloadRequest; Assert.IsNotNull(msg); Assert.AreEqual(msg.DataContentType, Dfs.WayneChina.HengshanPayTerminal.Support.DataContentType.FuelPriceList); } #endregion /************************** Data Content Request **************************/ #region Data Content request [TestMethod] public void DataContentRequest_could_be_parsed_Ok() { var dataContentReq = new byte[] { 0xFA, 0x02, 0x02, 0x3D, 0x00, 0x05, 0x27, 0x04, 0x00, 0x00, 0x0A, 0xFF, 0x07, 0x1E }; var msg = parser.Deserialize(dataContentReq) as DataContentRequest; Assert.IsNotNull(msg); Assert.AreEqual(msg.DataContentType, Dfs.WayneChina.HengshanPayTerminal.Support.DataContentType.FuelPriceList); } #endregion #region Data Content request [TestMethod] public void NewlyDeleted_Blacklist_Request_could_be_parsed_Ok() { var newlyDeletedBlacklistReq = new byte[] { 0xFA, 0x01, 0x01, 0x19, 0x00, 0x05, 0x27, 0x02, 0x00, 0x00, 0x01, 0xFF, 0x5C, 0x38 }; var dataContentReq = new byte[] { 0xFA, 0x02, 0x02, 0x3D, 0x00, 0x05, 0x27, 0x04, 0x00, 0x00, 0x0A, 0xFF, 0x07, 0x1E }; var msg = parser.Deserialize(newlyDeletedBlacklistReq) as DataContentRequest; Assert.IsNotNull(msg); Assert.AreEqual(msg.DataContentType, Dfs.WayneChina.HengshanPayTerminal.Support.DataContentType.NewlyDeletedBlacklist); Assert.AreEqual(msg.SegmentOffset, 0); Assert.AreEqual(msg.SegmentCount, 1); } #endregion /*********************** Query Gray Record Request ************************/ #region Query gray record request [TestMethod] public void QueryGrayRecordRequest_parsed_Ok() { var msg = parser.Deserialize(queryGrayRecordReqBytes) as QueryGrayRecordRequest; Assert.IsNotNull(msg); Assert.IsTrue(msg.Asn.Contains("10020383")); } [TestMethod] public void QueryGrayRecordRequest_ctc_is_ok() { var msg = parser.Deserialize(queryGrayRecordReqBytes) as QueryGrayRecordRequest; Assert.IsNotNull(msg); Assert.AreEqual(4, msg.Ctc); } [TestMethod] public void QueryGrayRecordRequest_balance_is_Ok() { var msg = parser.Deserialize(queryGrayRecordReqBytes) as QueryGrayRecordRequest; Assert.IsNotNull(msg); Assert.AreEqual(0x19e9, msg.Balance); } #endregion #endregion #region Full totalizer data [TestMethod] public void Full_totalizer_could_be_parsed_ok() { int volumeTotal = int.Parse("01EEBDBD", System.Globalization.NumberStyles.HexNumber); int amountTotal = int.Parse("0C553782", System.Globalization.NumberStyles.HexNumber); var msg = parser.Deserialize(fullTotalizerBytes) as Totalizer; Assert.IsNotNull(msg); Assert.AreEqual(1, msg.NozzleCount); Assert.AreEqual("01EEBDBD", msg.TotalizerData.First().VolumeTotal); Assert.AreEqual("0C553782", msg.TotalizerData.First().AmountTotal); } #endregion /**************************************************************************/ /************************ SERIALIZATION TESTS ***************************/ /**************************************************************************/ #region Serialization tests /**************************** Register Result *****************************/ #region Register reuslt [TestMethod] public void RegisterResult_serialize_Ok() { var expected = new byte[] { 0xFA, 0x01, 0x01, 0x01, 0x00, 0x22, 0x14, 0x00, 0x00, 0x00, 0x01, 0x12, 0x59, 0x8A, 0x93, 0xF2, 0x27, 0x54, 0xF4, 0x6B, 0x17, 0x20, 0x98, 0x8B, 0x8C, 0x1C, 0x24, 0x00, 0x00, 0x0A, 0xD7, 0xA2, 0xB2, 0xE1, 0xB3, 0xC9, 0xB9, 0xA6, 0x0D, 0x0A, 0xFF, 0x69, 0x2D }; RegisterResult registerResult = new RegisterResult { Prefix = 0xFA, SourceAddress = 1, DestinationAddress = 1, Handle = Convert.ToByte(Command.RegisterResult), TerminalId = "00000001", SystemKey = "12598A93F22754F46B1720988B8C1C24", Result = 0, StationNameLength = 0, AdditionalInfoLength = 10, AdditionalInfo = StringToByteArray("D7A2B2E1B3C9B9A60D0A").ToList(), }; registerResult.SetCallingParty(CallingParty.System); registerResult.SetSeqNo(1); var sourceBytes = parser.Serialize(registerResult); string hex = BitConverter.ToString(sourceBytes); Assert.IsTrue(ValueEquals(sourceBytes, expected)); } #endregion /************************** Check cmd response ****************************/ #region Check cmd response [TestMethod] public void CheckCmdResponse_serialize_Ok() { var expectedBytes = new byte[] { 0xFA, 0x01, 0x01, 0x73, 0x00, 0x12, 0x11, 0x20, 0x19, 0x03, 0x12, 0x08, 0x42, 0x48, 0x00, 0x29, 0xEB, 0x78, 0x24, 0xF4, 0x62, 0x00, 0x00, 0x00, 0xFF, 0x3C, 0x07 }; var timeStamp = DateTime.ParseExact("20190312084248", "yyyyMMddHHmmss", System.Globalization.CultureInfo.InvariantCulture); InquiryResult inquiryResult = new InquiryResult { Prefix = 0xFA, SourceAddress = 1, DestinationAddress = 1, Handle = Convert.ToByte(Command.Ver_info), BaseBlacklistVersion = 0x29, NewlyAddedBlacklistVersion = 0xEB, NewlyDeletedBlacklistVersion = 0x78, WhitelistVersion = 0x24, FuelPriceVersion = 0xF4, StationGeneralInfoVersion = 0x62, PrinterReceiptInfoVersion = 0x00, SoftwareDownloadFlag = 0x00, UnspecifiedField1 = 0x00, }; inquiryResult.SetCallingParty(CallingParty.Pump); inquiryResult.SetSeqNo(51); inquiryResult.SetTime(timeStamp); var sourceBytes = parser.Serialize(inquiryResult); string hex = BitConverter.ToString(sourceBytes); Assert.IsTrue(ValueEquals(sourceBytes, expectedBytes)); } #endregion /*********************** Change auth mode response ************************/ #region Change auth mode [TestMethod] public void ChangeAuthMode_serialize_Ok() { var expected = new byte[] { 0xFA, 0x01, 0x01, 0x73, 0x00, 0x04, 0x1B, 0x01, 0x01, 0x02, 0xFF, 0x3E, 0x25 }; ChangeAuthMode changeAuthModeReq = new ChangeAuthMode { Prefix = 0xFA, SourceAddress = 0x01, DestinationAddress = 0x01, Handle = Convert.ToByte(Command.ChangeAuthMode), FPCode = "0101", WorkMode = WorkMode.ServiceAutoAuth, }; changeAuthModeReq.SetCallingParty(CallingParty.Pump); changeAuthModeReq.SetSeqNo(51); var sourceBytes = parser.Serialize(changeAuthModeReq); string hex = BitConverter.ToString(sourceBytes); Assert.IsTrue(ValueEquals(sourceBytes, expected)); } #endregion /************************* Validate card response *************************/ #region Validate card result [TestMethod] public void ValidateCardResult_serialize_Ok() { var expected = new byte[] { 0xFA, 0x01, 0x01, 0x5C, 0x00, 0x1A, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x05, 0x53, 0x05, 0x7A, 0x40, 0x6D, 0xCA, 0x9D, 0x06, 0x00, 0x00, 0x00, 0x05, 0x7A, 0x40, 0x00, 0x00, 0xFF, 0x4E, 0x1F }; ValidateCardResult validateCardResult = new ValidateCardResult { Prefix = 0xFA, SourceAddress = 0x01, DestinationAddress = 0x01, Handle = Convert.ToByte(Command.ValidateCardResult), Asn = "00000000000010010553", MaxAllowedAmount = 0x057A40, PhysicalCardNo = 0x6DCA9D06, DiscountNo = 0x0000, CardBalance = 0x057A40, CardState = Dfs.WayneChina.HengshanPayTerminal.Support.CardState.Ok, AdditionalInfoLength = 0x00 }; validateCardResult.SetCallingParty(CallingParty.Pump); validateCardResult.SetSeqNo(28); var sourceBytes = parser.Serialize(validateCardResult); string hex = BitConverter.ToString(sourceBytes); Assert.IsTrue(ValueEquals(sourceBytes, expected)); } [TestMethod] public void ValidateCardResult_chip_card_serialize_Ok() { var expected = new byte[] { 0xFA, 0x01, 0x01, 0x3E, 0x00, 0x1A, 0x16, 0x11, 0x00, 0x01, 0x10, 0x00, 0x13, 0x80, 0x00, 0x10, 0x49, 0x07, 0x6A, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x6A, 0x26, 0x00, 0x00, 0xFF, 0x41, 0x66 }; ValidateCardResult validateCardResult = new ValidateCardResult { Prefix = 0xFA, SourceAddress = 0x01, DestinationAddress = 0x01, FrameSqNoByte = 0x3E, Handle = Convert.ToByte(Command.ValidateCardResult), Asn = "11000110001380001049", MaxAllowedAmount = 0x076A26, PhysicalCardNo = 0, DiscountNo = 0x0000, CardBalance = 0x00076A26, CardState = Dfs.WayneChina.HengshanPayTerminal.Support.CardState.Ok, AdditionalInfoLength = 0x00 }; var sourceBytes = parser.Serialize(validateCardResult); string hex = BitConverter.ToString(sourceBytes); Assert.IsTrue(ValueEquals(sourceBytes, expected)); } #endregion /******************************* Auth result ******************************/ #region Auth result [TestMethod] public void AuthResult_serialize_Ok() { var expected = new byte[] { 0xFA, 0x01, 0x01, 0x6A, 0x00, 0x15, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x05, 0x28, 0x00, 0x00, 0x03, 0x0A, 0x06, 0x0E, 0x01, 0x01, 0x00, 0x00, 0xFF, 0x5D, 0x73 }; AuthResult authResult = new AuthResult { Prefix = 0xFA, SourceAddress = 0x01, DestinationAddress = 0x01, Handle = Convert.ToByte(Command.AuthResult), Asn = "00000000000010010528", PosTtc = 0x30A, SeqNo = 0x60E, FuelCode = 0x0101, ResultCode = Dfs.WayneChina.HengshanPayTerminal.Support.AuthResultCode.Passed, AdditionalInfoLength = 0 }; authResult.SetCallingParty(CallingParty.Pump); authResult.SetSeqNo(42); var sourceBytes = parser.Serialize(authResult); string hex = BitConverter.ToString(sourceBytes); Assert.IsTrue(ValueEquals(sourceBytes, expected)); } #endregion /************************** Cancel auth result ****************************/ #region Cancel auth result [TestMethod] public void CancelAuthResult_serialize_Ok() { var expected = new byte[] { 0xFA, 0x03, 0x03, 0x35, 0x00, 0x15, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x05, 0x43, 0x00, 0x00, 0x2F, 0x77, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0xFF, 0x00, 0x3B }; var cancelAuthResult = new CancelAuthResult(); cancelAuthResult.Prefix = 0xFA; cancelAuthResult.DestinationAddress = 0x03; cancelAuthResult.SourceAddress = 0x03; cancelAuthResult.FrameSqNoByte = 0x35; cancelAuthResult.Handle = (byte)Command.CancelAuthResult; cancelAuthResult.Asn = "00000000000010010543"; cancelAuthResult.PosTtc = 0x2F77; cancelAuthResult.SeqNo = 0; cancelAuthResult.FPCode = 0x0303; cancelAuthResult.Result = 0; cancelAuthResult.AdditionalInfoLength = 0; var bytes = parser.Serialize(cancelAuthResult); string hex = BitConverter.ToString(bytes); Assert.IsTrue(ValueEquals(bytes, expected)); } #endregion /**************************** Fueling data ack ****************************/ #region Fueling data ack [TestMethod] public void FuelingDataProcessingResult_serialize_Ok() { var expected = new byte[] { 0xFA, 0x01, 0x01, 0x08, 0x00, 0x09, 0x35, 0x00, 0x00, 0x03, 0x23, 0x00, 0x0F, 0x01, 0x01, 0xFF, 0x07, 0x6D }; var fuelingDataResult = new FuelingDataProcessingResult { Prefix = 0xFA, SourceAddress = 0x01, DestinationAddress = 0x01, Handle = Convert.ToByte(Command.FuelingDataResult), PosTtc = 0x323, SeqNo = 0x0F, FPCode = 0x101 }; fuelingDataResult.SetCallingParty(CallingParty.System); fuelingDataResult.SetSeqNo(8); var sourceBytes = parser.Serialize(fuelingDataResult); string hex = BitConverter.ToString(sourceBytes); Assert.IsTrue(ValueEquals(sourceBytes, expected)); } #endregion /******************************* Payment ack ******************************/ #region Payment ack [TestMethod] public void PaymentData_serialize_Ok() { var expected = new byte[] { 0xFA, 0x01, 0x01, 0x5A, 0x00, 0x32, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x05, 0x53, 0x00, 0x00, 0x03, 0x22, 0x00, 0x0E, 0x00, 0x1D, 0x4D, 0x00, 0x1D, 0x4D, 0x00, 0x01, 0x44, 0x09, 0x0B, 0x04, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xFF, 0x3D, 0x6C }; var paymentData = new PaymentData { Prefix = 0xFA, SourceAddress = 0x01, DestinationAddress = 0x01, Handle = Convert.ToByte(Command.PaymentData), Asn = "00000000000010010553", PosTtc = 0x322, SeqNo = 0x0E, FillingAmount = 0x1D4D, PayAmount = 0x1D4D, FillingVolume = 0x144, Price = 0x90B, ProductCode = 0x407, C_Name = "00000000000000000000000000000000", FPCode = 0x101, Result = 0x00 }; paymentData.SetCallingParty(CallingParty.Pump); paymentData.SetSeqNo(0x1A); var sourceBytes = parser.Serialize(paymentData); string hex = BitConverter.ToString(sourceBytes); Assert.IsTrue(ValueEquals(sourceBytes, expected)); } #endregion /************************** Transaction data ack **************************/ #region Transaction Data ack [TestMethod] public void TransactionDataAck_serialize_Ok() { var expected = new byte[] { 0xFA, 0x01, 0x01, 0x5B, 0x00, 0x08, 0x32, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xFF, 0x2B, 0x6D }; var trxDataAck = new TransactionDataAck { Prefix = 0xFA, SourceAddress = 0x01, DestinationAddress = 0x01, Handle = Convert.ToByte(Command.TransactionDataAck), Result = 0x00, TerminalId = "00000001", UnspecifiedField1 = 0, }; trxDataAck.SetCallingParty(CallingParty.Pump); trxDataAck.SetSeqNo(0x1B); var sourceBytes = parser.Serialize(trxDataAck); string hex = BitConverter.ToString(sourceBytes); Assert.IsTrue(ValueEquals(sourceBytes, expected)); } #endregion /**************************** Data download ack ***************************/ #region Data download ack [TestMethod] public void DataBytesLength_serialize_Ok() { var expected = new byte[] { 0xFA, 0x02, 0x02, 0x2B, 0x00, 0x06, 0x26, 0x00, 0x00, 0x00, 0x32, 0x04, 0xFF, 0x5A, 0x31 }; var dataBytesLen = new DataBytesLength { Prefix = 0xFA, SourceAddress = 0x02, DestinationAddress = 0x02, Handle = Convert.ToByte(Command.DataBytesLength), DataLength = 0x32, DataContentType = Dfs.WayneChina.HengshanPayTerminal.Support.DataContentType.FuelPriceList }; dataBytesLen.SetCallingParty(CallingParty.System); dataBytesLen.SetSeqNo(0x2B); var sourceBytes = parser.Serialize(dataBytesLen); string hex = BitConverter.ToString(sourceBytes); Assert.IsTrue(ValueEquals(sourceBytes, expected)); } #endregion /*************************** Data content response ************************/ #region Data content response [TestMethod] public void DataContent_serialize_Ok() { System.Text.EncodingProvider provider = System.Text.CodePagesEncodingProvider.Instance; System.Text.Encoding.RegisterProvider(provider); var expected = new byte[] { 0xFA, 0x01, 0x01, 0x2A, 0x00, 0x45, 0x28, 0x04, 0x00, 0x00, 0x04, 0xC9, 0x20, 0x19, 0x08, 0x08, 0x08, 0x43, 0x01, 0x01, 0x10, 0x40, 0x39, 0x35, 0x23, 0xC6, 0xFB, 0xD3, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x1B, 0x39 }; var dataContent = new DataContent { Prefix = 0xFA, DestinationAddress = 0x01, SourceAddress = 0x01, FrameSqNoByte = 0x2A, Handle = (byte)Command.DataContent, DataContentType = Dfs.WayneChina.HengshanPayTerminal.Support.DataContentType.FuelPriceList, SegmentOffset = 0, SegmentCount = 4 }; var record = new FuelPriceRecord(); record.Density = 0; record.Version = 0xC9; record.EffectiveTime = "201908080843"; record.NozzleNo = 0x01; record.ValidPriceCount = 1; record.RecordCount = 1; record.FuelProductCode = 1040; record.FuelProductName = ByteArrayToString(System.Text.Encoding.GetEncoding("GB2312").GetBytes("95#汽油")).PadRight(64, '0'); record.Price1 = 0x2FE; dataContent.Content = parser.SerializeInnerElement(record).ToList(); var sourceBytes = parser.Serialize(dataContent); string hex = BitConverter.ToString(sourceBytes); Assert.IsTrue(ValueEquals(sourceBytes, expected)); } #endregion #region Fuel price record [TestMethod] public void FuelPriceRecord_serialize_Ok() { var expected = new byte[] { 0x3D, 0x20, 0x19, 0x03, 0x18, 0x13, 0x54, 0x01, 0x02, 0x10, 0x30, 0x39, 0x32, 0x23, 0xC6, 0xFB, 0xD3, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; var fpc = System.Text.Encoding.ASCII.GetBytes("393223C6FBD3CD00000000000000000000000000000000000000000000000000"); FuelPriceRecord record = new FuelPriceRecord { Version = 0x3D, EffectiveTime = "201903181354", RecordCount = 1, NozzleNo = 2, FuelProductCode = 1030, FuelProductName = "393223C6FBD3CD00000000000000000000000000000000000000000000000000", Density = 0, ValidPriceCount = 1, Price1 = 0x314 }; var bytes = parser.SerializeInnerElement(record); string hex = BitConverter.ToString(bytes); Assert.IsTrue(ValueEquals(bytes, expected)); } #endregion #region Listed cards [TestMethod] public void ListedCards_serialize_Ok() { var expected = new byte[] { 0x00, 0x2A, 0x20, 0x14, 0x03, 0x10, 0x21, 0x14, 0x03, 0x10, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F }; ListedCardRecord record = new ListedCardRecord { Version = 0x2A, ValidStartDate = "20140310", ExpiryDate = "21140310", Region = Convert.ToString(ushort.MaxValue), CardCount = 15 }; var bytes = parser.SerializeInnerElement(record); Assert.IsTrue(ValueEquals(bytes, expected)); } #endregion /**************************** Lock Pump Request ***************************/ #region Lock pump [TestMethod] public void LockPump_is_serialized_Ok() { //FA01010D000444010101FF2C69 // ----<-Fueling point // --<01=Lock pump byte[] lockPumpReq = new byte[] { 0xFA, 0x01, 0x01, 0x0D, 0x00, 0x04, 0x44, 0x01, 0x01, 0x01, 0xFF, 0x2C, 0x69 }; LockOrUnlockPumpRequest lockRequest = new LockOrUnlockPumpRequest { Prefix = 0xFA, SourceAddress = 1, DestinationAddress = 1, FrameSqNoByte = 0x0D, Handle = Convert.ToByte(Command.LockOrUnlockPump), FPCode = "0101", OperationType = Dfs.WayneChina.HengshanPayTerminal.Support.LockUnlockOperation.Lock, }; var bytes = parser.Serialize(lockRequest); string hex = BitConverter.ToString(bytes); Assert.IsTrue(ValueEquals(bytes, lockPumpReq)); } #endregion #region QueryGrayRecord result [TestMethod] public void QueryGrayRecordResult_serialize_Ok() { var expected = new byte[] { 0xFA, 0x04, 0x04, 0x1F, 0x00, 0x30, 0x22, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x03, 0x83, 0x00, 0x00, 0x19, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x19, 0x11, 0x19, 0x17, 0x07, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x62, 0x31 }; var result = new QueryGrayRecordResult(); result.Prefix = 0xFA; result.DestinationAddress = 4; result.SourceAddress = 4; result.FrameSqNoByte = 0x1F; result.Handle = 0x22; result.Match = 1; result.Asn = "00000000000010020383"; result.Balance = 0x19e9; //result.Amount = 0; result.Amount1 = 0; result.Ctc = 4; result.Time = "20191119170715"; result.Gmac = "00000000"; result.PsamTid = "000000000000"; result.PsamTtc = 0; result.Volume = 0; var bytes = parser.Serialize(result); string hex = BitConverter.ToString(bytes); Assert.IsTrue(ValueEquals(bytes, expected)); } #endregion ///////////////////////// SERIALIZATION END ////////////////// #endregion #region Helper method public static bool ValueEquals(IEnumerable array1, IEnumerable array2) { if (array1 == null && array2 == null) { return true; } if ((array1 == null) || (array2 == null)) { return false; } if (array1.Count() != array2.Count()) { return false; } if (array1.Equals(array2)) { return true; } else { for (int Index = 0; Index < array1.Count(); Index++) { if (!Equals(array1.ElementAt(Index), array2.ElementAt(Index))) { return false; } } } return true; } public byte[] StringToByteArray(string hex) { int numberChars = hex.Length; byte[] bytes = new byte[numberChars / 2]; for (int i = 0; i < numberChars; i += 2) bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); return bytes; } public static string ByteArrayToString(byte[] ba) { return BitConverter.ToString(ba).Replace("-", ""); } #endregion } }