from unittest import TestCase, main import os, pty import curses.ascii import threading from faker import Faker from payment_card_identifier import VISA from telium.payment import TeliumData from telium import * class FakeTeliumDevice: def __init__(self): self._master, self._slave = pty.openpty() self._s_name = os.ttyname(self._slave) self._fake = Faker() self._fake_device = threading.Thread(target=self.__run) def run_instance(self): self._fake_device.start() @property def s_name(self): return self._s_name @staticmethod def _has_signal(data, signal): return (data[0] if six.PY3 else ord(data[0])) == curses.ascii.controlnames.index(signal) @staticmethod def _create_signal(signal): return bytes([curses.ascii.controlnames.index(signal)]) if six.PY3 else bytes(chr(curses.ascii.controlnames.index(signal))) def _wait_signal(self, signal): return FakeTeliumDevice._has_signal(os.read(self._master, 1), signal) def _send_signal(self, signal): os.write(self._master, FakeTeliumDevice._create_signal(signal)) def __run(self): if self._wait_signal('ENQ'): self._send_signal('ACK') raw_data = os.read(self._master, TERMINAL_ANSWER_COMPLETE_SIZE) if TeliumData.lrc_check(raw_data) is True: payment_pending = TeliumAsk.decode(raw_data) print('from slave : ', payment_pending.__dict__) self._send_signal('ACK') # Accept data from master if not self._wait_signal('EOT'): self._send_signal('NAK') exit(1) if payment_pending.answer_flag == TERMINAL_ANSWER_SET_FULLSIZED: my_response = TeliumResponse( payment_pending.pos_number, TERMINAL_PAYMENT_SUCCESS, payment_pending.amount, payment_pending.payment_mode, (self._fake.credit_card_number(card_type='visa16') + ' ' + '0' * 37), payment_pending.currency_numeric, '0' * 10 ) elif payment_pending.answer_flag == TERMINAL_ANSWER_SET_SMALLSIZED: my_response = TeliumResponse( payment_pending.pos_number, TERMINAL_PAYMENT_SUCCESS, payment_pending.amount, payment_pending.payment_mode, None, payment_pending.currency_numeric, '0' * 10 ) else: self._send_signal('NAK') exit(1) self._send_signal('ENQ') if self._wait_signal('ACK'): os.write( self._master, bytes(my_response.encode(), TERMINAL_DATA_ENCODING) if six.PY3 else bytes(my_response.encode()) ) if self._wait_signal('ACK'): self._send_signal('EOT') exit(0) self._send_signal('NAK') else: self._send_signal('NAK') exit(1) else: self._send_signal('NAK') exit(1) class TestTPE(TestCase): def setUp(self): self._fake_device = FakeTeliumDevice() def test_demande_paiement_fullsized_repport(self): self._fake_device.run_instance() my_telium_instance = Telium(self._fake_device.s_name) self.assertFalse(my_telium_instance.debugging) self.assertTrue(my_telium_instance.is_open) self.assertEqual(my_telium_instance.timeout, 1) self.assertTrue(my_telium_instance.close()) self.assertTrue(my_telium_instance.open()) # Construct our payment infos my_payment = TeliumAsk( '1', # Checkout ID 1 TERMINAL_ANSWER_SET_FULLSIZED, # Ask for fullsized repport TERMINAL_MODE_PAYMENT_DEBIT, # Ask for debit TERMINAL_TYPE_PAYMENT_CARD, # Using a card TERMINAL_NUMERIC_CURRENCY_EUR, # Set currency to EUR TERMINAL_REQUEST_ANSWER_WAIT_FOR_TRANSACTION, # Do not wait for transaction end for terminal answer TERMINAL_FORCE_AUTHORIZATION_DISABLE, # Let device choose if we should ask for authorization 12.5 # Ask for 12.5 EUR ) # Send payment infos to device self.assertTrue(my_telium_instance.ask(my_payment)) my_answer = my_telium_instance.verify(my_payment) self.assertIsNotNone(my_answer) print('from master : ', my_answer.__dict__) self.assertEqual(my_answer.transaction_result, 0) self.assertEqual(my_answer.currency_numeric, TERMINAL_NUMERIC_CURRENCY_EUR) self.assertEqual(my_answer.private, '0' * 10) self.assertIsInstance(my_answer.card_type, VISA) self.assertEqual(my_answer.card_type.numbers, my_answer.repport.split(' ')[0]) self.assertIsInstance(my_answer.__dict__.get('_card_type'), dict) self.assertEqual(my_answer.card_id[0], '4') self.assertTrue(my_telium_instance.close()) self.assertFalse(my_telium_instance.close()) def test_demande_paiement_smallsized_repport(self): self._fake_device.run_instance() my_telium_instance = Telium(self._fake_device.s_name, debugging=True) self.assertFalse(my_telium_instance.open()) self.assertTrue(my_telium_instance.debugging) # Construct our payment infos my_payment = TeliumAsk( '1', # Checkout ID 1 TERMINAL_ANSWER_SET_SMALLSIZED, # Ask for fullsized repport TERMINAL_MODE_PAYMENT_DEBIT, # Ask for debit TERMINAL_TYPE_PAYMENT_CARD, # Using a card TERMINAL_NUMERIC_CURRENCY_EUR, # Set currency to EUR TERMINAL_REQUEST_ANSWER_WAIT_FOR_TRANSACTION, # Do not wait for transaction end for terminal answer TERMINAL_FORCE_AUTHORIZATION_DISABLE, # Let device choose if we should ask for authorization 91.1 # Ask for 12.5 EUR ) # Send payment infos to device self.assertTrue(my_telium_instance.ask(my_payment, True)) my_answer = my_telium_instance.verify(my_payment) self.assertIsNotNone(my_answer) print('from master : ', my_answer.__dict__) self.assertEqual(my_answer.transaction_result, 0) self.assertEqual(my_answer.currency_numeric, TERMINAL_NUMERIC_CURRENCY_EUR) self.assertEqual(my_answer.private, '0' * 10) self.assertEqual(my_answer.repport, '') def test_initialization_failed(self): my_telium_instance = Telium(self._fake_device.s_name) # Construct our payment infos my_payment = TeliumAsk( '1', # Checkout ID 1 TERMINAL_ANSWER_SET_SMALLSIZED, # Ask for fullsized repport TERMINAL_MODE_PAYMENT_DEBIT, # Ask for debit TERMINAL_TYPE_PAYMENT_CARD, # Using a card TERMINAL_NUMERIC_CURRENCY_EUR, # Set currency to EUR TERMINAL_REQUEST_ANSWER_WAIT_FOR_TRANSACTION, # Do not wait for transaction end for terminal answer TERMINAL_FORCE_AUTHORIZATION_DISABLE, # Let device choose if we should ask for authorization 91.1 # Ask for 12.5 EUR ) with self.assertRaises(TerminalInitializationFailedException): my_telium_instance.ask(my_payment) if __name__ == '__main__': main()