def setUp(self): self.queues = gen_queue_dict() self.contact_list = ContactList(nicks=['Alice'])
class TestRxWindow(TFCTestCase): def setUp(self) -> None: """Pre-test actions.""" self.contact_list = ContactList( nicks=['Alice', 'Bob', 'Charlie', LOCAL_ID]) self.group_list = GroupList(groups=['test_group', 'test_group2']) self.settings = Settings() self.packet_list = PacketList() self.ts = datetime.fromtimestamp(1502750000) self.time = self.ts.strftime('%H:%M:%S.%f')[:-4] group = self.group_list.get_group('test_group') group.members = list( map(self.contact_list.get_contact_by_address_or_nick, ['Alice', 'Bob', 'Charlie'])) def create_window(self, uid: bytes): """Create new RxWindow object.""" return RxWindow(uid, self.contact_list, self.group_list, self.settings, self.packet_list) def test_command_window_creation(self) -> None: window = self.create_window(WIN_UID_COMMAND) self.assertEqual(window.type, WIN_TYPE_COMMAND) self.assertEqual(window.name, WIN_TYPE_COMMAND) def test_file_window_creation(self) -> None: window = self.create_window(WIN_UID_FILE) self.assertEqual(window.type, WIN_TYPE_FILE) def test_contact_window_creation(self) -> None: window = self.create_window(nick_to_pub_key("Alice")) self.assertEqual(window.type, WIN_TYPE_CONTACT) self.assertEqual(window.window_contacts[0].onion_pub_key, nick_to_pub_key("Alice")) self.assertEqual(window.name, 'Alice') def test_group_window_creation(self) -> None: window = self.create_window(group_name_to_group_id('test_group')) self.assertEqual(window.type, WIN_TYPE_GROUP) self.assertEqual(window.window_contacts[0].onion_pub_key, nick_to_pub_key("Alice")) self.assertEqual(window.name, 'test_group') def test_invalid_uid_raises_se(self) -> None: self.assert_se( "Invalid window 'mfqwcylbmfqwcylbmfqwcylbmfqwcylbmfqwcylbmfqwcylbmfqwbfad'.", self.create_window, ONION_SERVICE_PUBLIC_KEY_LENGTH * b'a') self.assert_se("Invalid window '2dnAMoWNfTXAJ'.", self.create_window, GROUP_ID_LENGTH * b'a') self.assert_se("Invalid window '<unable to encode>'.", self.create_window, b'bad_uid') def test_window_iterates_over_message_tuples(self) -> None: # Setup window = self.create_window(nick_to_pub_key("Alice")) window.message_log = 5 * [ (datetime.now(), 'Lorem ipsum', nick_to_pub_key("Alice"), ORIGIN_CONTACT_HEADER, False, False) ] # Test for mt in window: self.assertEqual(mt[1:], ("Lorem ipsum", nick_to_pub_key("Alice"), ORIGIN_CONTACT_HEADER, False, False)) def test_len_returns_number_of_messages_in_window(self) -> None: # Setup window = self.create_window(nick_to_pub_key("Alice")) window.message_log = 5 * [ (datetime.now(), "Lorem ipsum", nick_to_pub_key("Alice"), ORIGIN_CONTACT_HEADER, False, False) ] # Test self.assertEqual(len(window), 5) def test_remove_contacts(self) -> None: # Setup window = self.create_window(group_name_to_group_id('test_group')) # Test self.assertEqual(len(window.window_contacts), 3) self.assertIsNone( window.remove_contacts([ nick_to_pub_key("Alice"), nick_to_pub_key("Bob"), nick_to_pub_key("DoesNotExist") ])) self.assertEqual(len(window.window_contacts), 1) def test_add_contacts(self) -> None: # Setup window = self.create_window(group_name_to_group_id('test_group')) window.window_contacts = [ self.contact_list.get_contact_by_address_or_nick('Alice') ] # Test self.assertIsNone( window.add_contacts([ nick_to_pub_key("Alice"), nick_to_pub_key("Bob"), nick_to_pub_key("DoesNotExist") ])) self.assertEqual(len(window.window_contacts), 2) def test_reset_window(self) -> None: # Setup window = self.create_window(group_name_to_group_id('test_group')) window.message_log = \ [(datetime.now(), "Hi everybody", nick_to_pub_key("Alice"), ORIGIN_USER_HEADER, False, False), (datetime.now(), "Hi David", nick_to_pub_key("Alice"), ORIGIN_CONTACT_HEADER, False, False), (datetime.now(), "Hi David", nick_to_pub_key("Bob"), ORIGIN_CONTACT_HEADER, False, False)] # Test self.assertIsNone(window.reset_window()) self.assertEqual(len(window), 0) def test_has_contact(self) -> None: window = self.create_window(group_name_to_group_id('test_group')) self.assertTrue(window.has_contact(nick_to_pub_key("Alice"))) self.assertFalse(window.has_contact(nick_to_pub_key("DoesNotExist"))) def test_create_handle_dict(self) -> None: # Setup window = self.create_window(group_name_to_group_id('test_group')) message_log = [ (datetime.now(), "Lorem ipsum", nick_to_pub_key("Alice"), ORIGIN_CONTACT_HEADER, False, False), (datetime.now(), "Lorem ipsum", nick_to_pub_key("Bob"), ORIGIN_USER_HEADER, False, False), (datetime.now(), "Lorem ipsum", nick_to_pub_key("Charlie"), ORIGIN_CONTACT_HEADER, False, False), (datetime.now(), "Lorem ipsum", nick_to_pub_key("Charlie"), ORIGIN_CONTACT_HEADER, True, False), (datetime.now(), "Lorem ipsum", nick_to_pub_key("Charlie"), ORIGIN_CONTACT_HEADER, False, False), (datetime.now(), "Lorem ipsum", nick_to_pub_key("David"), ORIGIN_CONTACT_HEADER, False, False), (datetime.now(), "Lorem ipsum", nick_to_pub_key("Eric"), ORIGIN_CONTACT_HEADER, False, False) ] # Test self.assertIsNone(window.create_handle_dict(message_log)) self.assertEqual( window.handle_dict, { nick_to_pub_key("Alice"): 'Alice', nick_to_pub_key("Bob"): 'Bob', nick_to_pub_key("Charlie"): 'Charlie', nick_to_pub_key("David"): nick_to_short_address("David"), nick_to_pub_key("Eric"): nick_to_short_address("Eric") }) def test_get_command_handle(self) -> None: # Setup window = self.create_window(WIN_UID_COMMAND) window.is_active = True # Test self.assertEqual( window.get_handle(self.ts, WIN_UID_COMMAND, ORIGIN_USER_HEADER), f"{self.time} -!- ") def test_get_contact_handle(self) -> None: # Setup window = self.create_window(nick_to_pub_key("Alice")) window.is_active = True window.handle_dict = {nick_to_pub_key("Alice"): 'Alice'} # Test self.assertEqual( window.get_handle(self.ts, nick_to_pub_key("Alice"), ORIGIN_USER_HEADER), f"{self.time} Me: ") self.assertEqual( window.get_handle(self.ts, nick_to_pub_key("Alice"), ORIGIN_CONTACT_HEADER), f"{self.time} Alice: ") window.is_active = False self.assertEqual( window.get_handle(self.ts, nick_to_pub_key("Alice"), ORIGIN_USER_HEADER), f"{self.time} Me (private message): ") self.assertEqual( window.get_handle(self.ts, nick_to_pub_key("Alice"), ORIGIN_CONTACT_HEADER), f"{self.time} Alice (private message): ") def test_get_group_contact_handle(self) -> None: # Setup window = self.create_window(group_name_to_group_id('test_group')) window.is_active = True window.handle_dict = { nick_to_pub_key("Alice"): 'Alice', nick_to_pub_key("Charlie"): 'Charlie', nick_to_pub_key("David"): nick_to_short_address("David"), nick_to_pub_key("Eric"): nick_to_short_address("Eric") } # Test self.assertEqual( window.get_handle(self.ts, nick_to_pub_key("Alice"), ORIGIN_USER_HEADER), f"{self.time} Me: ") self.assertEqual( window.get_handle(self.ts, nick_to_pub_key("Charlie"), ORIGIN_CONTACT_HEADER), f"{self.time} Charlie: ") window.is_active = False self.assertEqual( window.get_handle(self.ts, nick_to_pub_key("Alice"), ORIGIN_USER_HEADER), f"{self.time} Me (group test_group): ") self.assertEqual( window.get_handle(self.ts, nick_to_pub_key("Charlie"), ORIGIN_CONTACT_HEADER), f"{self.time} Charlie (group test_group): ") @mock.patch('time.sleep', return_value=None) def test_print_to_inactive_window_preview_on_short_message(self, _: Any) -> None: # Setup window = self.create_window(nick_to_pub_key("Alice")) window.handle_dict = {nick_to_pub_key("Alice"): 'Alice'} window.is_active = False window.settings = Settings(new_message_notify_preview=True) msg_tuple = (self.ts, "Hi Bob", nick_to_pub_key("Bob"), ORIGIN_USER_HEADER, False, False) # Test self.assert_prints( f"{BOLD_ON}{self.time} Me (private message): {NORMAL_TEXT}" f"Hi Bob\n{CURSOR_UP_ONE_LINE}{CLEAR_ENTIRE_LINE}", window.print, msg_tuple) @mock.patch('time.sleep', return_value=None) def test_print_to_inactive_window_preview_on_long_message(self, _: Any) -> None: # Setup window = self.create_window(nick_to_pub_key("Alice")) window.is_active = False window.handle_dict = {nick_to_pub_key("Alice"): 'Alice'} window.settings = Settings(new_message_notify_preview=True) long_message = ( "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque consequat libero et lao" "reet egestas. Aliquam a arcu malesuada, elementum metus eget, elementum mi. Vestibulum i" "d arcu sem. Ut sodales odio sed viverra mollis. Praesent gravida ante tellus, pellentesq" "ue venenatis massa placerat quis. Nullam in magna porta, hendrerit sem vel, dictum ipsum" ". Ut sagittis, ipsum ut bibendum ornare, ex lorem congue metus, vel posuere metus nulla " "at augue.") msg_tuple = (self.ts, long_message, nick_to_pub_key("Bob"), ORIGIN_USER_HEADER, False, False) # Test self.assert_prints( f"{BOLD_ON}{self.time} Me (private message): {NORMAL_TEXT}Lorem ipsum dolor sit " f"amet, consectetu…\n{CURSOR_UP_ONE_LINE}{CLEAR_ENTIRE_LINE}", window.print, msg_tuple) @mock.patch('time.sleep', return_value=None) def test_print_to_inactive_window_preview_off(self, _: Any) -> None: # Setup window = self.create_window(nick_to_pub_key("Alice")) window.is_active = False window.handle_dict = {nick_to_pub_key("Alice"): 'Alice'} window.settings = Settings(new_message_notify_preview=False) msg_tuple = (self.ts, "Hi Bob", nick_to_pub_key("Bob"), ORIGIN_USER_HEADER, False, False) # Test self.assert_prints( f"{BOLD_ON}{self.time} Me (private message): {NORMAL_TEXT}{BOLD_ON}1 unread message{NORMAL_TEXT}\n" f"{CURSOR_UP_ONE_LINE}{CLEAR_ENTIRE_LINE}", window.print, msg_tuple) def test_print_to_active_window_no_date_change(self) -> None: # Setup window = self.create_window(nick_to_pub_key("Alice")) window.previous_msg_ts = datetime.fromtimestamp(1502750000) window.is_active = True window.handle_dict = {nick_to_pub_key("Bob"): 'Bob'} window.settings = Settings(new_message_notify_preview=False) msg_tuple = (self.ts, "Hi Alice", nick_to_pub_key("Bob"), ORIGIN_CONTACT_HEADER, False, False) # Test self.assert_prints( f"{BOLD_ON}{self.time} Bob: {NORMAL_TEXT}Hi Alice\n", window.print, msg_tuple) def test_print_to_active_window_with_date_change_and_whisper(self) -> None: # Setup window = self.create_window(nick_to_pub_key("Alice")) window.previous_msg_ts = datetime.fromtimestamp(1501750000) window.is_active = True window.handle_dict = {nick_to_pub_key("Bob"): 'Bob'} window.settings = Settings(new_message_notify_preview=False) msg_tuple = (self.ts, "Hi Alice", nick_to_pub_key("Bob"), ORIGIN_CONTACT_HEADER, True, False) self.time = self.ts.strftime('%H:%M:%S.%f')[:-4] # Test self.assert_prints( f"""\ {BOLD_ON}00:00 -!- Day changed to 2017-08-15{NORMAL_TEXT} {BOLD_ON}{self.time} Bob (whisper): {NORMAL_TEXT}Hi Alice """, window.print, msg_tuple) def test_print_to_active_window_with_date_change_and_whisper_empty_message( self) -> None: # Setup window = self.create_window(nick_to_pub_key("Alice")) window.previous_msg_ts = datetime.fromtimestamp(1501750000) window.is_active = True window.handle_dict = {nick_to_pub_key("Bob"): 'Bob'} window.settings = Settings(new_message_notify_preview=False) msg_tuple = (self.ts, " ", nick_to_pub_key("Bob"), ORIGIN_CONTACT_HEADER, True, False) # Test self.assert_prints( f"""\ {BOLD_ON}00:00 -!- Day changed to 2017-08-15{NORMAL_TEXT} {BOLD_ON}{self.time} Bob (whisper): {NORMAL_TEXT} """, window.print, msg_tuple) @mock.patch('time.sleep', return_value=None) def test_print_new(self, _: Any) -> None: # Setup window = self.create_window(nick_to_pub_key("Alice")) # Test self.assertIsNone( window.add_new(self.ts, "Hi Alice", nick_to_pub_key("Bob"), ORIGIN_CONTACT_HEADER, output=True)) self.assertEqual(len(window.message_log), 1) self.assertEqual(window.handle_dict[nick_to_pub_key("Bob")], 'Bob') def test_redraw_message_window(self) -> None: # Setup window = self.create_window(nick_to_pub_key("Alice")) window.is_active = True window.message_log = [(self.ts, "Hi Alice", nick_to_pub_key("Bob"), ORIGIN_CONTACT_HEADER, False, False)] window.unread_messages = 1 # Test self.assert_prints( f"""\ {CLEAR_ENTIRE_SCREEN}{CURSOR_LEFT_UP_CORNER} ------------------------------- Unread Messages -------------------------------- {BOLD_ON}{self.time} Bob: {NORMAL_TEXT}Hi Alice """, window.redraw) self.assertEqual(window.unread_messages, 0) def test_redraw_empty_window(self) -> None: # Setup window = self.create_window(nick_to_pub_key("Alice")) window.is_active = True window.message_log = [] # Test self.assert_prints( f"""\ {CLEAR_ENTIRE_SCREEN}{CURSOR_LEFT_UP_CORNER} {BOLD_ON} This window for Alice is currently empty. {NORMAL_TEXT}\n """, window.redraw) @mock.patch('time.sleep', return_value=None) def test_redraw_file_win(self, _: Any) -> None: # Setup self.packet_list.packets = [ Packet(type=FILE, name='testfile.txt', assembly_pt_list=5 * [b'a'], packets=10, size="100.0KB", contact=create_contact('Bob')), Packet(type=FILE, name='testfile2.txt', assembly_pt_list=7 * [b'a'], packets=100, size="15.0KB", contact=create_contact('Charlie')) ] # Test window = self.create_window(WIN_UID_FILE) self.assert_prints( f"""\ File name Size Sender Complete ──────────────────────────────────────────────────────────────────────────────── testfile.txt 100.0KB Bob 50.00% testfile2.txt 15.0KB Charlie 7.00% {6*(CURSOR_UP_ONE_LINE+CLEAR_ENTIRE_LINE)}""", window.redraw_file_win) @mock.patch('time.sleep', return_value=None) def test_redraw_empty_file_win(self, _: Any) -> None: # Setup self.packet_list.packet_l = [] # Test window = self.create_window(WIN_UID_FILE) self.assert_prints( f"""\ {BOLD_ON} No file transmissions currently in progress. {NORMAL_TEXT} {3*(CURSOR_UP_ONE_LINE+CLEAR_ENTIRE_LINE)}""", window.redraw_file_win)
class TestChContactSetting(TFCTestCase): def setUp(self) -> None: """Pre-test actions.""" self.ts = datetime.fromtimestamp(1502750000) self.contact_list = ContactList(nicks=['Alice', 'Bob']) self.group_list = GroupList(groups=['test_group', 'test_group2']) self.window_list = WindowList(contact_list=self.contact_list, group_list=self.group_list) self.args = self.ts, self.window_list, self.contact_list, self.group_list def test_invalid_window_raises_se(self) -> None: # Setup cmd_data = ENABLE + nick_to_pub_key("Bob") header = CH_LOGGING self.contact_list = ContactList(nicks=['Alice']) self.window_list = WindowList(contact_list=self.contact_list, group_list=self.group_list) # Test self.assert_se(f"Error: Found no window for '{nick_to_short_address('Bob')}'.", ch_contact_s, cmd_data, *self.args, header) def test_setting_change_contact(self) -> None: # Setup self.window = self.window_list.get_window(nick_to_pub_key("Bob")) self.window.type = WIN_TYPE_CONTACT self.window.type_print = 'contact' self.window.window_contacts = self.contact_list.contacts bob = self.contact_list.get_contact_by_address_or_nick("Bob") # Test for attr, header in [('log_messages', CH_LOGGING), ('notifications', CH_NOTIFY), ('file_reception', CH_FILE_RECV)]: for s in [ENABLE, ENABLE, DISABLE, DISABLE]: cmd_data = s + nick_to_pub_key("Bob") self.assertIsNone(ch_contact_s(cmd_data, *self.args, header)) self.assertEqual(bob.__getattribute__(attr), (s == ENABLE)) def test_setting_change_group(self) -> None: # Setup self.window = self.window_list.get_window(group_name_to_group_id('test_group')) self.window.type = WIN_TYPE_GROUP self.window.type_print = 'group' self.window.window_contacts = self.group_list.get_group('test_group').members # Test for attr, header in [('log_messages', CH_LOGGING), ('notifications', CH_NOTIFY), ('file_reception', CH_FILE_RECV)]: for s in [ENABLE, ENABLE, DISABLE, DISABLE]: cmd_data = s + group_name_to_group_id('test_group') self.assertIsNone(ch_contact_s(cmd_data, *self.args, header)) if header in [CH_LOGGING, CH_NOTIFY]: self.assertEqual(self.group_list.get_group('test_group').__getattribute__(attr), (s == ENABLE)) if header == CH_FILE_RECV: for m in self.group_list.get_group('test_group').members: self.assertEqual(m.file_reception, (s == ENABLE)) def test_setting_change_all(self) -> None: # Setup self.window = self.window_list.get_window(nick_to_pub_key("Bob")) self.window.type = WIN_TYPE_CONTACT self.window.type_print = 'contact' self.window.window_contacts = self.contact_list.contacts # Test for attr, header in [('log_messages', CH_LOGGING), ('notifications', CH_NOTIFY), ('file_reception', CH_FILE_RECV)]: for s in [ENABLE, ENABLE, DISABLE, DISABLE]: cmd_data = s.upper() + US_BYTE self.assertIsNone(ch_contact_s(cmd_data, *self.args, header)) if header in [CH_LOGGING, CH_NOTIFY]: for c in self.contact_list.get_list_of_contacts(): self.assertEqual(c.__getattribute__(attr), (s == ENABLE)) for g in self.group_list.groups: self.assertEqual(g.__getattribute__(attr), (s == ENABLE)) if header == CH_FILE_RECV: for c in self.contact_list.get_list_of_contacts(): self.assertEqual(c.__getattribute__(attr), (s == ENABLE))
class TestLocalKey(TFCTestCase): def setUp(self) -> None: """Pre-test actions.""" self.contact_list = ContactList() self.settings = Settings() self.queues = gen_queue_dict() self.args = self.contact_list, self.settings, self.queues def tearDown(self) -> None: """Post-test actions.""" tear_queues(self.queues) def test_new_local_key_when_traffic_masking_is_enabled_raises_soft_error( self) -> None: self.settings.traffic_masking = True self.contact_list.contacts = [create_contact(LOCAL_ID)] self.assert_se("Error: Command is disabled during traffic masking.", new_local_key, *self.args) @mock.patch('time.sleep', return_value=None) @mock.patch('builtins.input', side_effect=['bad', '', '61']) @mock.patch('os.getrandom', side_effect=[ SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a', XCHACHA20_NONCE_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a' ]) @mock.patch('os.urandom', return_value=CONFIRM_CODE_LENGTH * b'a') @mock.patch('os.system', return_value=None) def test_new_local_key(self, *_: Any) -> None: # Setup self.settings.nc_bypass_messages = False self.settings.traffic_masking = False # Test self.assertIsNone(new_local_key(*self.args)) local_contact = self.contact_list.get_contact_by_pub_key(LOCAL_PUBKEY) self.assertEqual(local_contact.onion_pub_key, LOCAL_PUBKEY) self.assertEqual(local_contact.nick, LOCAL_NICK) self.assertEqual( local_contact.tx_fingerprint, blake2b(b58encode(blake2b(SYMMETRIC_KEY_LENGTH * b'a')).encode())) self.assertEqual(local_contact.rx_fingerprint, bytes(FINGERPRINT_LENGTH)) self.assertFalse(local_contact.log_messages) self.assertFalse(local_contact.file_reception) self.assertFalse(local_contact.notifications) self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1) cmd, account, tx_key, rx_key, tx_hek, rx_hek = self.queues[ KEY_MANAGEMENT_QUEUE].get() self.assertEqual(cmd, KDB_ADD_ENTRY_HEADER) self.assertEqual(account, LOCAL_PUBKEY) for key in [tx_key, rx_key, tx_hek, rx_hek]: self.assertIsInstance(key, bytes) self.assertEqual(len(key), SYMMETRIC_KEY_LENGTH) @mock.patch('time.sleep', return_value=None) @mock.patch('builtins.input', side_effect=KeyboardInterrupt) @mock.patch('os.getrandom', lambda x, flags: x * b'a') def test_keyboard_interrupt_raises_soft_error(self, *_: Any) -> None: self.assert_se("Local key setup aborted.", new_local_key, *self.args)
def test_loop(self): # Setup queues = gen_queue_dict() settings = Settings(traffic_masking=False) gateway = Gateway() key_list = KeyList() window = TxWindow(log_messages=True) contact_list = ContactList(nicks=['Alice', LOCAL_ID]) window.contact_list = contact_list window.window_contacts = [contact_list.get_contact_by_address_or_nick('Alice')] user_input = UserInput(plaintext='test') delay = 0.01 def queue_delayer(): """Place datagrams into queue after delay.""" time.sleep(delay) queue_command(b'test', settings, queues) time.sleep(delay) queue_to_nc(PUBLIC_KEY_DATAGRAM_HEADER + TFC_PUBLIC_KEY_LENGTH * b'a' + nick_to_pub_key('Alice'), # 1 queues[RELAY_PACKET_QUEUE]) time.sleep(delay) queue_to_nc(UNENCRYPTED_DATAGRAM_HEADER + UNENCRYPTED_WIPE_COMMAND, queues[RELAY_PACKET_QUEUE]) # 2 time.sleep(delay) queue_to_nc(UNENCRYPTED_DATAGRAM_HEADER + UNENCRYPTED_EXIT_COMMAND, queues[RELAY_PACKET_QUEUE]) # 3 time.sleep(delay) queues[KEY_MANAGEMENT_QUEUE].put((KDB_ADD_ENTRY_HEADER, LOCAL_PUBKEY, # 4 SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a')) time.sleep(delay) queue_message(user_input, window, settings, queues) # 5 time.sleep(delay) queue_message(user_input, window, settings, queues) # 6 time.sleep(delay) queues[KEY_MANAGEMENT_QUEUE].put((KDB_ADD_ENTRY_HEADER, nick_to_pub_key('Alice'), SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a')) time.sleep(delay) queue_message(user_input, window, settings, queues) # 7 time.sleep(delay) queue_message(user_input, window, settings, queues) # 8 time.sleep(delay) queues[SENDER_MODE_QUEUE].put(settings) threading.Thread(target=queue_delayer).start() # Test settings, m_buffer = standard_sender_loop(queues, gateway, key_list) self.assertIsInstance(settings, Settings) self.assertEqual(m_buffer, {nick_to_pub_key('Alice'): []}) self.assertEqual(len(gateway.packets), 8) self.assertEqual(queues[EXIT_QUEUE].qsize(), 2) # Teardown tear_queues(queues)
def test_loop(self): # Setup queues = { MESSAGE_PACKET_QUEUE: Queue(), FILE_PACKET_QUEUE: Queue(), COMMAND_PACKET_QUEUE: Queue(), NH_PACKET_QUEUE: Queue(), LOG_PACKET_QUEUE: Queue(), NOISE_PACKET_QUEUE: Queue(), NOISE_COMMAND_QUEUE: Queue(), KEY_MANAGEMENT_QUEUE: Queue(), WINDOW_SELECT_QUEUE: Queue(), EXIT_QUEUE: Queue() } settings = Settings(session_traffic_masking=True) gateway = Gateway() key_list = KeyList(nicks=['Alice', LOCAL_ID]) window = TxWindow(log_messages=True) contact_list = ContactList(nicks=['Alice', LOCAL_ID]) window.contact_list = contact_list window.window_contacts = [contact_list.get_contact('Alice')] user_input = UserInput(plaintext='test') queue_message(user_input, window, settings, queues[MESSAGE_PACKET_QUEUE]) queue_message(user_input, window, settings, queues[MESSAGE_PACKET_QUEUE]) queue_message(user_input, window, settings, queues[MESSAGE_PACKET_QUEUE]) queue_command(b'test', settings, queues[COMMAND_PACKET_QUEUE]) queue_command(b'test', settings, queues[COMMAND_PACKET_QUEUE]) queue_command(b'test', settings, queues[COMMAND_PACKET_QUEUE], window) queue_to_nh(UNENCRYPTED_PACKET_HEADER + UNENCRYPTED_EXIT_COMMAND, settings, queues[NH_PACKET_QUEUE]) queue_to_nh(UNENCRYPTED_PACKET_HEADER + UNENCRYPTED_WIPE_COMMAND, settings, queues[NH_PACKET_QUEUE]) def queue_delayer(): time.sleep(0.1) queues[WINDOW_SELECT_QUEUE].put((window, True)) # Test threading.Thread(target=queue_delayer).start() self.assertIsNone( sender_loop(queues, settings, gateway, key_list, unittest=True)) threading.Thread(target=queue_delayer).start() self.assertIsNone( sender_loop(queues, settings, gateway, key_list, unittest=True)) threading.Thread(target=queue_delayer).start() self.assertIsNone( sender_loop(queues, settings, gateway, key_list, unittest=True)) self.assertEqual(len(gateway.packets), 8) self.assertEqual(queues[EXIT_QUEUE].qsize(), 2) # Teardown for key in queues: while not queues[key].empty(): queues[key].get() time.sleep(0.1) queues[key].close()
class TestKeyExchange(TFCTestCase): def setUp(self) -> None: """Pre-test actions.""" self.contact_list = ContactList(nicks=[LOCAL_ID]) self.settings = Settings() self.queues = gen_queue_dict() self.args = self.contact_list, self.settings, self.queues def tearDown(self) -> None: """Post-test actions.""" tear_queues(self.queues) @mock.patch('shutil.get_terminal_size', return_value=[200, 200]) @mock.patch('builtins.input', return_value=b58encode(bytes(TFC_PUBLIC_KEY_LENGTH), public_key=True)) def test_zero_public_key_raises_soft_error(self, *_: Any) -> None: self.assert_se("Error: Zero public key", start_key_exchange, nick_to_pub_key("Alice"), 'Alice', *self.args) @mock.patch('shutil.get_terminal_size', return_value=[200, 200]) @mock.patch('builtins.input', return_value=b58encode((TFC_PUBLIC_KEY_LENGTH - 1) * b'a', public_key=True)) def test_invalid_public_key_length_raises_soft_error(self, *_: Any) -> None: self.assert_se("Error: Invalid public key length", start_key_exchange, nick_to_pub_key("Alice"), 'Alice', *self.args) @mock.patch( 'builtins.input', side_effect=[ '', # Empty message should resend key VALID_ECDHE_PUB_KEY[:-1], # Short key should fail VALID_ECDHE_PUB_KEY + 'a', # Long key should fail VALID_ECDHE_PUB_KEY[:-1] + 'a', # Invalid key should fail VALID_ECDHE_PUB_KEY, # Correct key 'No' ]) # Fingerprint mismatch) @mock.patch('time.sleep', return_value=None) @mock.patch('shutil.get_terminal_size', return_value=[200, 200]) def test_fingerprint_mismatch_raises_soft_error(self, *_: Any) -> None: self.assert_se("Error: Fingerprint mismatch", start_key_exchange, nick_to_pub_key("Alice"), 'Alice', *self.args) @mock.patch( 'builtins.input', side_effect=[ '', # Resend public key VALID_ECDHE_PUB_KEY, # Correct key 'Yes', # Fingerprint match '', # Resend contact data 'ff', # Invalid confirmation code blake2b(nick_to_pub_key('Alice'), digest_size=CONFIRM_CODE_LENGTH).hex() ]) @mock.patch('shutil.get_terminal_size', return_value=[200, 200]) @mock.patch('time.sleep', return_value=None) def test_successful_exchange(self, *_: Any) -> None: self.assertIsNone( start_key_exchange(nick_to_pub_key("Alice"), 'Alice', *self.args)) contact = self.contact_list.get_contact_by_pub_key( nick_to_pub_key("Alice")) self.assertEqual(contact.onion_pub_key, nick_to_pub_key("Alice")) self.assertEqual(contact.nick, 'Alice') self.assertEqual(contact.kex_status, KEX_STATUS_VERIFIED) self.assertIsInstance(contact.tx_fingerprint, bytes) self.assertIsInstance(contact.rx_fingerprint, bytes) self.assertEqual(len(contact.tx_fingerprint), FINGERPRINT_LENGTH) self.assertEqual(len(contact.rx_fingerprint), FINGERPRINT_LENGTH) self.assertFalse(contact.log_messages) self.assertFalse(contact.file_reception) self.assertTrue(contact.notifications) self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 2) self.assertEqual(self.queues[RELAY_PACKET_QUEUE].qsize(), 2) cmd, account, tx_key, rx_key, tx_hek, rx_hek = self.queues[ KEY_MANAGEMENT_QUEUE].get() self.assertEqual(cmd, KDB_ADD_ENTRY_HEADER) self.assertEqual(account, nick_to_pub_key("Alice")) self.assertEqual(len(tx_key), SYMMETRIC_KEY_LENGTH) for key in [tx_key, rx_key, tx_hek, rx_hek]: self.assertIsInstance(key, bytes) self.assertEqual(len(key), SYMMETRIC_KEY_LENGTH) @mock.patch( 'builtins.input', side_effect=[ '', # Resend public key VALID_ECDHE_PUB_KEY, # Correct key KeyboardInterrupt, # Skip fingerprint verification '', # Manual proceed for warning message blake2b(nick_to_pub_key('Alice'), digest_size=CONFIRM_CODE_LENGTH).hex() ]) @mock.patch('time.sleep', return_value=None) @mock.patch('shutil.get_terminal_size', return_value=[200, 200]) def test_successful_exchange_skip_fingerprint_verification( self, *_: Any) -> None: self.assertIsNone( start_key_exchange(nick_to_pub_key("Alice"), 'Alice', *self.args)) contact = self.contact_list.get_contact_by_pub_key( nick_to_pub_key("Alice")) self.assertEqual(contact.onion_pub_key, nick_to_pub_key("Alice")) self.assertEqual(contact.nick, 'Alice') self.assertEqual(contact.kex_status, KEX_STATUS_UNVERIFIED) @mock.patch( 'os.getrandom', side_effect=[SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a']) @mock.patch('builtins.input', side_effect=[ KeyboardInterrupt, VALID_ECDHE_PUB_KEY, 'Yes', blake2b(nick_to_pub_key('Alice'), digest_size=CONFIRM_CODE_LENGTH).hex() ]) @mock.patch('time.sleep', return_value=None) @mock.patch('shutil.get_terminal_size', return_value=[200, 200]) def test_successful_exchange_with_previous_key(self, *_: Any) -> None: # Test caching of private key self.assert_se("Key exchange interrupted.", start_key_exchange, nick_to_pub_key('Alice'), 'Alice', *self.args) alice = self.contact_list.get_contact_by_address_or_nick('Alice') self.assertEqual(alice.kex_status, KEX_STATUS_PENDING) # Test re-using private key self.assertIsNone( start_key_exchange(nick_to_pub_key('Alice'), 'Alice', *self.args)) self.assertIsNone(alice.tfc_private_key) self.assertEqual(alice.kex_status, KEX_STATUS_VERIFIED)
def setUp(self) -> None: """Pre-test actions.""" self.queues = gen_queue_dict() self.contact_list = ContactList(nicks=['Alice'])
class TestKeyExchange(TFCTestCase): def setUp(self): self.o_input = builtins.input self.contact_list = ContactList() self.settings = Settings() self.queues = { COMMAND_PACKET_QUEUE: Queue(), NH_PACKET_QUEUE: Queue(), KEY_MANAGEMENT_QUEUE: Queue() } def tearDown(self): builtins.input = self.o_input for key in self.queues.keys(): while not self.queues[key].empty(): self.queues[key].get() time.sleep(0.1) self.queues[key].close() def test_zero_public_key_raises_fr(self): # Setup builtins.input = lambda _: b58encode(bytes(32)) # Test self.assertFR("Error: Zero public key", start_key_exchange, '*****@*****.**', '*****@*****.**', 'Alice', self.contact_list, self.settings, self.queues) def test_raises_fr_during_fingerprint_mismatch(self): # Setup input_list = [ 'resend', # Resend should resend key '5JCVapni8CR2PEXr5v92cCY2QgSd4cztR2v3L3vK2eair7dGHi', # Short key should fail '5JCVapni8CR2PEXr5v92cCY2QgSd4cztR2v3L3vK2eair7dGHiHa', # Long key should fail '5JCVapni8CR2PEXr5v92cCY2QgSd4cztR2v3L3vK2eair7dGHia', # Invalid key should fail '5JCVapni8CR2PEXr5v92cCY2QgSd4cztR2v3L3vK2eair7dGHiH', # Correct key 'No' ] # Fingerprint mismatch gen = iter(input_list) builtins.input = lambda _: str(next(gen)) # Test self.assertFR("Error: Fingerprint mismatch", start_key_exchange, '*****@*****.**', '*****@*****.**', 'Alice', self.contact_list, self.settings, self.queues) def test_successful_exchange(self): # Setup input_list = [ '5JCVapni8CR2PEXr5v92cCY2QgSd4cztR2v3L3vK2eair7dGHiH', # Correct key 'Yes' ] # Fingerprint match gen = iter(input_list) builtins.input = lambda _: str(next(gen)) # Test self.assertIsNone( start_key_exchange('*****@*****.**', '*****@*****.**', 'Alice', self.contact_list, self.settings, self.queues)) time.sleep(0.1) contact = self.contact_list.get_contact('*****@*****.**') self.assertEqual(contact.rx_account, '*****@*****.**') self.assertEqual(contact.tx_account, '*****@*****.**') self.assertEqual(contact.nick, 'Alice') self.assertIsInstance(contact.tx_fingerprint, bytes) self.assertIsInstance(contact.rx_fingerprint, bytes) self.assertEqual(len(contact.tx_fingerprint), FINGERPRINT_LEN) self.assertEqual(len(contact.rx_fingerprint), FINGERPRINT_LEN) self.assertFalse(contact.log_messages) self.assertFalse(contact.file_reception) self.assertTrue(contact.notifications) self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1) cmd, account, tx_key, rx_key, tx_hek, rx_hek = self.queues[ KEY_MANAGEMENT_QUEUE].get() self.assertEqual(cmd, KDB_ADD_ENTRY_HEADER) self.assertEqual(account, '*****@*****.**') self.assertEqual(len(tx_key), KEY_LENGTH) for key in [tx_key, rx_key, tx_hek, rx_hek]: self.assertIsInstance(key, bytes) self.assertEqual(len(key), KEY_LENGTH)
def setUp(self): self.contact_list = ContactList(nicks=['Alice', 'Bob']) self.group_list = GroupList(groups=['testgroup']) self.settings = Settings(key_list=['key1', 'key2'])
def test_loop(self, *_): # Setup queues = gen_queue_dict() kek = SYMMETRIC_KEY_LENGTH * b'a' conf_code = bytes(1) tx_pub_key = nick_to_pub_key('Bob') o_sleep = self.o_sleep test_delay = 0.1 def queue_packet(mk, hk, tx_harac, packet, onion_pub_key=None): """Create encrypted datagram.""" if onion_pub_key is None: header = b'' queue = queues[COMMAND_DATAGRAM_HEADER] packet = split_to_assembly_packets(packet, COMMAND)[0] else: header = onion_pub_key + ORIGIN_CONTACT_HEADER queue = queues[MESSAGE_DATAGRAM_HEADER] packet = split_to_assembly_packets(packet, MESSAGE)[0] encrypted_harac = encrypt_and_sign(int_to_bytes(tx_harac), hk) encrypted_message = encrypt_and_sign(packet, mk) encrypted_packet = header + encrypted_harac + encrypted_message queue.put((datetime.datetime.now(), encrypted_packet)) def queue_delayer(): """Place datagrams into queue after delay.""" o_sleep(test_delay) local_harac = INITIAL_HARAC tx_harac = INITIAL_HARAC local_hek = SYMMETRIC_KEY_LENGTH * b'a' file_key = SYMMETRIC_KEY_LENGTH * b'b' local_key = SYMMETRIC_KEY_LENGTH * b'a' tx_mk = SYMMETRIC_KEY_LENGTH * b'a' tx_hk = SYMMETRIC_KEY_LENGTH * b'a' # Queue local key packet local_key_packet = encrypt_and_sign(local_key + local_hek + conf_code, key=kek) queues[LOCAL_KEY_DATAGRAM_HEADER].put( (datetime.datetime.now(), local_key_packet)) o_sleep(test_delay) # Select file window command = WIN_SELECT + WIN_UID_FILE queue_packet(local_key, tx_hk, local_harac, command) local_key, local_harac = rotate_key(local_key, local_harac) o_sleep(test_delay) # Select local window command = WIN_SELECT + WIN_UID_LOCAL queue_packet(local_key, tx_hk, local_harac, command) local_key, local_harac = rotate_key(local_key, local_harac) o_sleep(test_delay) # A message that goes to buffer queue_packet( tx_mk, tx_hk, tx_harac, bool_to_bytes(False) + PRIVATE_MESSAGE_HEADER + b'Hi Bob', tx_pub_key) tx_mk, tx_harac = rotate_key(tx_mk, tx_harac) # ECDHE keyset for Bob command = KEY_EX_ECDHE + nick_to_pub_key("Bob") + ( 4 * SYMMETRIC_KEY_LENGTH * b'a') + str_to_bytes('Bob') queue_packet(local_key, tx_hk, local_harac, command) local_key, local_harac = rotate_key(local_key, local_harac) o_sleep(test_delay) # Message for Bob queue_packet( tx_mk, tx_hk, tx_harac, bool_to_bytes(False) + PRIVATE_MESSAGE_HEADER + b'Hi Bob', tx_pub_key) tx_mk, tx_harac = rotate_key(tx_mk, tx_harac) o_sleep(test_delay) # Enable file reception for Bob command = CH_FILE_RECV + ENABLE.upper() + US_BYTE queue_packet(local_key, tx_hk, local_harac, command) o_sleep(test_delay) # File packet from Bob ct = encrypt_and_sign(b'test', file_key) f_hash = blake2b(ct) packet = nick_to_pub_key('Bob') + ORIGIN_CONTACT_HEADER + ct queues[FILE_DATAGRAM_HEADER].put((datetime.datetime.now(), packet)) o_sleep(test_delay) # File key packet from Bob queue_packet( tx_mk, tx_hk, tx_harac, bool_to_bytes(False) + FILE_KEY_HEADER + base64.b85encode(f_hash + file_key), tx_pub_key) o_sleep(test_delay) # Queue exit message to break the loop o_sleep(0.5) queues[UNITTEST_QUEUE].put(EXIT) o_sleep(test_delay) threading.Thread(target=queue_delayer).start() # Test self.assertIsNone( output_loop(queues, Gateway(), Settings(), ContactList(), KeyList(), GroupList(), MasterKey(), stdin_fd=1, unittest=True)) # Teardown tear_queues(queues)
def setUp(self): self.contact_list = ContactList(nicks=['Alice'])
class TestNewFile(TFCTestCase): def setUp(self): self.unittest_dir = cd_unittest() self.ts = datetime.now() self.packet = b'' self.file_keys = dict() self.file_buf = dict() self.contact_list = ContactList(nicks=['Alice']) self.window_list = WindowList() self.file_key = SYMMETRIC_KEY_LENGTH * b'a' self.settings = Settings() self.compressed = zlib.compress(str_to_bytes("test_file.txt") + b'file_data', level=COMPRESSION_LEVEL) self.args = self.file_keys, self.file_buf, self.contact_list, self.window_list, self.settings def tearDown(self): cleanup(self.unittest_dir) def test_unknown_account_raises_fr(self): # Setup file_ct = encrypt_and_sign(self.compressed, self.file_key) packet = nick_to_pub_key('Bob') + ORIGIN_CONTACT_HEADER + file_ct # Test self.assert_fr("File from an unknown account.", new_file, self.ts, packet, *self.args) def test_disabled_file_reception_raises_fr(self): # Setup file_ct = encrypt_and_sign(self.compressed, self.file_key) packet = nick_to_pub_key('Alice') + ORIGIN_CONTACT_HEADER + file_ct self.contact_list.get_contact_by_address_or_nick( 'Alice').file_reception = False # Test self.assert_fr( "Alert! Discarded file from Alice as file reception for them is disabled.", new_file, self.ts, packet, *self.args) def test_valid_file_without_key_is_cached(self): # Setup file_ct = encrypt_and_sign(self.compressed, self.file_key) file_hash = blake2b(file_ct) packet = nick_to_pub_key('Alice') + ORIGIN_CONTACT_HEADER + file_ct # Test self.assertIsNone(new_file(self.ts, packet, *self.args)) self.assertEqual(self.file_buf[nick_to_pub_key('Alice') + file_hash], (self.ts, file_ct)) @mock.patch('time.sleep', return_value=None) def test_valid_file_with_key_is_processed(self, _): # Setup file_ct = encrypt_and_sign(self.compressed, self.file_key) file_hash = blake2b(file_ct) packet = nick_to_pub_key('Alice') + ORIGIN_CONTACT_HEADER + file_ct self.file_keys = { (nick_to_pub_key('Alice') + file_hash): self.file_key } self.args = self.file_keys, self.file_buf, self.contact_list, self.window_list, self.settings # Test self.assertIsNone(new_file(self.ts, packet, *self.args))
def setUp(self): self.contact_list = ContactList() self.settings = Settings() self.onion_service = OnionService() self.gateway = Gateway() self.args = self.contact_list, self.settings, self.onion_service, self.gateway
def setUp(self) -> None: """Pre-test actions.""" self.contact_list = ContactList(nicks=['Alice', 'Bob']) self.group_list = GroupList(groups=['test_group'])
class TestPSK(TFCTestCase): def setUp(self): if 'TRAVIS' not in os.environ or not os.environ['TRAVIS'] == 'true': self.o_getrandom = os.getrandom self.o_input = builtins.input self.o_getpass = getpass.getpass self.contact_list = ContactList() self.settings = Settings(disable_gui_dialog=True) self.queues = { COMMAND_PACKET_QUEUE: Queue(), KEY_MANAGEMENT_QUEUE: Queue() } if 'TRAVIS' not in os.environ or not os.environ['TRAVIS'] == 'true': os.getrandom = lambda n, flags: n * b'\x00' getpass.getpass = lambda _: 'test_password' input_list = [ '/root/', # Invalid directory '.' ] # Valid directory gen = iter(input_list) builtins.input = lambda _: str(next(gen)) def tearDown(self): builtins.input = self.o_input getpass.getpass = self.o_getpass if 'TRAVIS' not in os.environ or not os.environ['TRAVIS'] == 'true': os.getrandom = self.o_getrandom with ignored(OSError): os.remove('[email protected] - Give to [email protected]') for key in self.queues.keys(): while not self.queues[key].empty(): self.queues[key].get() time.sleep(0.1) self.queues[key].close() def test_psk_creation(self): self.assertIsNone( create_pre_shared_key('*****@*****.**', '*****@*****.**', 'Alice', self.contact_list, self.settings, self.queues)) contact = self.contact_list.get_contact('*****@*****.**') self.assertEqual(contact.rx_account, '*****@*****.**') self.assertEqual(contact.tx_account, '*****@*****.**') self.assertEqual(contact.nick, 'Alice') self.assertEqual(contact.tx_fingerprint, bytes(FINGERPRINT_LEN)) self.assertEqual(contact.rx_fingerprint, bytes(FINGERPRINT_LEN)) self.assertFalse(contact.log_messages) self.assertFalse(contact.file_reception) self.assertTrue(contact.notifications) cmd, account, tx_key, rx_key, tx_hek, rx_hek = self.queues[ KEY_MANAGEMENT_QUEUE].get() self.assertEqual(cmd, KDB_ADD_ENTRY_HEADER) self.assertEqual(account, '*****@*****.**') for key in [tx_key, rx_key, tx_hek, rx_hek]: self.assertIsInstance(key, bytes) self.assertEqual(len(key), KEY_LENGTH) self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1) self.assertTrue( os.path.isfile('[email protected] - Give to [email protected]'))
def setUp(self) -> None: """Pre-test actions.""" self.contact_list = ContactList(nicks=['Alice', 'Bob']) self.group_list = GroupList(groups=['test_group']) self.settings = Settings(key_list=['key1', 'key2']) self.gateway = Gateway()
class TestLocalKey(TFCTestCase): def setUp(self): self.o_input = builtins.input self.o_urandom = os.urandom if 'TRAVIS' not in os.environ or not os.environ['TRAVIS'] == 'true': self.o_getrandom = os.getrandom self.contact_list = ContactList() self.settings = Settings() self.queues = { COMMAND_PACKET_QUEUE: Queue(), NH_PACKET_QUEUE: Queue(), KEY_MANAGEMENT_QUEUE: Queue() } def tearDown(self): builtins.input = self.o_input os.urandom = self.o_urandom if 'TRAVIS' not in os.environ or not os.environ['TRAVIS'] == 'true': os.getrandom = self.o_getrandom for key in self.queues.keys(): while not self.queues[key].empty(): self.queues[key].get() time.sleep(0.1) self.queues[key].close() def test_new_local_key_when_traffic_masking_is_enabled_raises_fr(self): # Setup self.settings.session_traffic_masking = True # Test self.assertFR("Error: Command is disabled during traffic masking.", new_local_key, self.contact_list, self.settings, self.queues) def test_new_local_key(self): # Setup self.settings.nh_bypass_messages = False self.settings.session_traffic_masking = False if 'TRAVIS' not in os.environ or not os.environ['TRAVIS'] == 'true': os.getrandom = lambda n, flags: n * b'\xff' os.urandom = lambda n: n * b'\xff' input_list = ['bad', 'resend', 'ff'] gen = iter(input_list) builtins.input = lambda _: str(next(gen)) # Test self.assertIsNone( new_local_key(self.contact_list, self.settings, self.queues)) time.sleep(0.1) local_contact = self.contact_list.get_contact(LOCAL_ID) self.assertEqual(local_contact.rx_account, LOCAL_ID) self.assertEqual(local_contact.tx_account, LOCAL_ID) self.assertEqual(local_contact.nick, LOCAL_ID) self.assertEqual(local_contact.tx_fingerprint, bytes(FINGERPRINT_LEN)) self.assertEqual(local_contact.rx_fingerprint, bytes(FINGERPRINT_LEN)) self.assertFalse(local_contact.log_messages) self.assertFalse(local_contact.file_reception) self.assertFalse(local_contact.notifications) self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1) cmd, account, tx_key, rx_key, tx_hek, rx_hek = self.queues[ KEY_MANAGEMENT_QUEUE].get() self.assertEqual(cmd, KDB_ADD_ENTRY_HEADER) self.assertEqual(account, LOCAL_ID) for key in [tx_key, rx_key, tx_hek, rx_hek]: self.assertIsInstance(key, bytes) self.assertEqual(len(key), KEY_LENGTH)
class TestSendFile(TFCTestCase): def setUp(self) -> None: """Pre-test actions.""" self.unit_test_dir = cd_unit_test() self.settings = Settings() self.queues = gen_queue_dict() self.window = TxWindow() self.onion_service = OnionService() self.contact_list = ContactList(nicks=['Alice', 'Bob', 'Charlie']) self.args = self.settings, self.queues, self.window def tearDown(self) -> None: """Post-test actions.""" cleanup(self.unit_test_dir) tear_queues(self.queues) def test_traffic_masking_raises_soft_error(self) -> None: self.settings.traffic_masking = True self.assert_se("Error: Command is disabled during traffic masking.", send_file, "testfile.txt", *self.args) def test_missing_file_raises_soft_error(self) -> None: self.assert_se("Error: File not found.", send_file, "testfile.txt", *self.args) def test_empty_file_raises_soft_error(self) -> None: # Setup open('testfile.txt', 'wb+').close() # Test self.assert_se("Error: Target file is empty.", send_file, "testfile.txt", *self.args) @mock.patch('time.sleep', return_value=None) def test_file_transmission_to_contact(self, _: Any) -> None: # Setup self.window.window_contacts = [ self.contact_list.get_contact_by_address_or_nick('Alice') ] self.window.type_print = 'contact' input_data = os.urandom(5) with open('testfile.txt', 'wb+') as f: f.write(input_data) # Test self.assertIsNone(send_file("testfile.txt", *self.args)) self.assertEqual(self.queues[MESSAGE_PACKET_QUEUE].qsize(), 1) self.assertEqual(self.queues[RELAY_PACKET_QUEUE].qsize(), 1) @mock.patch('time.sleep', return_value=None) def test_file_transmission_to_group(self, _: Any) -> None: # Setup self.window.window_contacts = [ self.contact_list.get_contact_by_address_or_nick('Alice'), self.contact_list.get_contact_by_address_or_nick('Bob') ] self.window.type_print = 'group' input_data = os.urandom(5) with open('testfile.txt', 'wb+') as f: f.write(input_data) self.assertIsNone(send_file("testfile.txt", *self.args)) self.assertEqual(self.queues[MESSAGE_PACKET_QUEUE].qsize(), 2) self.assertEqual(self.queues[RELAY_PACKET_QUEUE].qsize(), 1)
class TestTxWindow(TFCTestCase): def setUp(self) -> None: """Pre-test actions.""" self.contact_list = ContactList(['Alice', 'Bob', LOCAL_ID]) self.group_list = GroupList(groups=['test_group', 'test_group_2']) self.window = TxWindow(self.contact_list, self.group_list) self.window.group = self.group_list.get_group('test_group') self.window.type = WIN_TYPE_GROUP self.settings = Settings() self.queues = gen_queue_dict() self.onion_service = OnionService() self.gateway = Gateway() self.args = self.settings, self.queues, self.onion_service, self.gateway def tearDown(self) -> None: """Post-test actions.""" tear_queues(self.queues) def test_window_iterates_over_contacts(self) -> None: # Setup self.window.window_contacts = self.contact_list.contacts # Test for c in self.window: self.assertIsInstance(c, Contact) def test_len_returns_number_of_contacts_in_window(self) -> None: # Setup self.window.window_contacts = [ self.contact_list.get_contact_by_pub_key(nick_to_pub_key('Alice')), self.contact_list.get_contact_by_pub_key(nick_to_pub_key('Bob')) ] # Test self.assertEqual(len(self.window), 2) def test_group_window_change_during_traffic_masking_raises_se( self) -> None: # Setup self.settings.traffic_masking = True self.window.uid = 'test_group' # Test self.assert_se("Error: Can't change window during traffic masking.", self.window.select_tx_window, *self.args, selection='test_group_2', cmd=True) def test_contact_window_change_during_traffic_masking_raises_se( self) -> None: # Setup self.settings.traffic_masking = True self.window.uid = nick_to_pub_key("Alice") # Test self.assert_se("Error: Can't change window during traffic masking.", self.window.select_tx_window, *self.args, selection=nick_to_onion_address("Bob"), cmd=True) def test_contact_window_reload_during_traffic_masking(self) -> None: # Setup self.settings.traffic_masking = True self.window.uid = nick_to_pub_key("Alice") # Test self.assertIsNone( self.window.select_tx_window( *self.args, selection=nick_to_onion_address("Alice"), cmd=True)) self.assertEqual(self.window.uid, nick_to_pub_key("Alice")) def test_group_window_reload_during_traffic_masking(self) -> None: # Setup self.settings.traffic_masking = True self.window.name = 'test_group' self.window.uid = group_name_to_group_id('test_group') # Test self.assertIsNone( self.window.select_tx_window(*self.args, selection='test_group', cmd=True)) self.assertEqual(self.window.uid, group_name_to_group_id('test_group')) def test_invalid_selection_raises_se(self) -> None: # Setup self.window.uid = nick_to_pub_key("Alice") # Test self.assert_se("Error: No contact/group was found.", self.window.select_tx_window, *self.args, selection=nick_to_onion_address("Charlie"), cmd=True) @mock.patch('builtins.input', return_value=nick_to_onion_address("Bob")) def test_window_selection_during_traffic_masking(self, *_: Any) -> None: # Setup self.settings.traffic_masking = True self.window.uid = None # Test self.assertIsNone(self.window.select_tx_window(*self.args)) self.assertEqual(self.queues[WINDOW_SELECT_QUEUE].qsize(), 1) @mock.patch('builtins.input', return_value=nick_to_onion_address("Bob")) def test_contact_window_selection_from_input(self, *_: Any) -> None: # Setup self.window.uid = None # Test self.assertIsNone(self.window.select_tx_window(*self.args)) self.assertEqual(self.window.uid, nick_to_pub_key("Bob")) def test_group_window_selection_from_command(self) -> None: # Setup self.window.uid = None self.assertIsNone( self.window.select_tx_window(*self.args, selection='test_group', cmd=True)) self.assertEqual(self.window.uid, group_name_to_group_id('test_group')) def test_deselect_window(self) -> None: # Setup self.window.window_contacts = self.contact_list.contacts self.window.contact = self.contact_list.get_contact_by_address_or_nick( "Bob") self.window.name = 'Bob' self.window.type = WIN_TYPE_CONTACT self.window.uid = nick_to_pub_key("Bob") # Test self.assertIsNone(self.window.deselect()) self.assertIsNone(self.window.contact) self.assertEqual(self.window.name, '') self.assertEqual(self.window.type, '') self.assertEqual(self.window.uid, b'') def test_is_selected(self) -> None: self.window.name = '' self.assertFalse(self.window.is_selected()) self.window.name = nick_to_pub_key("Bob") self.assertTrue(self.window.is_selected()) def test_update_log_messages_for_contact(self) -> None: # Setup self.window.type = WIN_TYPE_CONTACT self.window.log_messages = None self.window.contact = self.contact_list.get_contact_by_address_or_nick( 'Alice') self.window.contact.log_messages = False # Test self.assertIsNone(self.window.update_log_messages()) self.assertFalse(self.window.log_messages) def test_update_log_messages_for_group(self) -> None: # Setup self.window.type = WIN_TYPE_GROUP self.window.log_messages = None self.window.group = self.group_list.get_group('test_group') self.window.group.log_messages = False # Test self.assertIsNone(self.window.update_log_messages()) self.assertFalse(self.window.log_messages) def test_update_group_win_members_if_group_is_available(self) -> None: # Setup self.window.window_contacts = [] self.window.group = None self.window.group_id = group_name_to_group_id('test_group') self.window.name = 'test_group' self.window.type = WIN_TYPE_GROUP # Test self.assertIsNone(self.window.update_window(self.group_list)) self.assertEqual(self.window.group, self.group_list.get_group('test_group')) self.assertEqual(self.window.window_contacts, self.window.group.members) def test_window_contact_is_reloaded_when_contact_is_active(self) -> None: # Setup self.window.type = WIN_TYPE_CONTACT self.window.contact = create_contact('Alice') self.window.window_contacts = [self.window.contact] self.assertIsNot( self.window.contact, self.window.contact_list.get_contact_by_pub_key( nick_to_pub_key('Alice'))) self.assertIsNot( self.window.window_contacts[0], self.window.contact_list.get_contact_by_pub_key( nick_to_pub_key('Alice'))) # Test self.assertIsNone(self.window.update_window(self.group_list)) self.assertIs( self.window.contact, self.window.contact_list.get_contact_by_pub_key( nick_to_pub_key('Alice'))) self.assertIs( self.window.window_contacts[0], self.window.contact_list.get_contact_by_pub_key( nick_to_pub_key('Alice'))) def test_deactivate_window_if_group_is_not_available(self) -> None: # Setup self.window.window_contacts = [] self.window.group = None self.window.name = 'test_group_3' self.window.type = WIN_TYPE_GROUP # Test self.assertIsNone(self.window.update_window(self.group_list)) self.assertIsNone(self.window.contact) self.assertEqual(self.window.name, '') self.assertEqual(self.window.type, '') self.assertEqual(self.window.uid, b'') @mock.patch('time.sleep', return_value=None) @mock.patch('builtins.input', side_effect=[ 'Alice', VALID_ECDHE_PUB_KEY, 'yes', blake2b(nick_to_pub_key('Alice'), digest_size=CONFIRM_CODE_LENGTH).hex() ]) @mock.patch('shutil.get_terminal_size', return_value=[200, 200]) def test_selecting_pending_contact_starts_key_exchange(self, *_: Any) -> None: # Setup alice = self.contact_list.get_contact_by_address_or_nick('Alice') bob = self.contact_list.get_contact_by_address_or_nick('Bob') alice.kex_status = KEX_STATUS_PENDING bob.kex_status = KEX_STATUS_PENDING # Test self.assertIsNone(self.window.select_tx_window(*self.args)) self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 2) self.assertEqual(self.queues[WINDOW_SELECT_QUEUE].qsize(), 0) self.assertEqual(alice.kex_status, KEX_STATUS_VERIFIED) @mock.patch('time.sleep', return_value=None) @mock.patch('builtins.input', side_effect=[ '/add', nick_to_onion_address('Alice'), 'Alice', '', VALID_ECDHE_PUB_KEY, 'yes', blake2b(nick_to_pub_key('Alice'), digest_size=CONFIRM_CODE_LENGTH).hex() ]) @mock.patch('shutil.get_terminal_size', return_value=[200, 200]) def test_adding_new_contact_from_contact_selection(self, *_: Any) -> None: # Setup alice = self.contact_list.get_contact_by_address_or_nick('Alice') alice.kex_status = KEX_STATUS_PENDING # Test self.assert_se('New contact added.', self.window.select_tx_window, *self.args) self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1) self.assertEqual(self.queues[WINDOW_SELECT_QUEUE].qsize(), 0) self.assertEqual(alice.kex_status, KEX_STATUS_VERIFIED) @mock.patch('time.sleep', return_value=None) @mock.patch('builtins.input', side_effect=['/rm ']) def test_missing_account_when_removing_raises_se(self, *_: Any) -> None: self.assert_se("Error: No account specified.", self.window.select_tx_window, *self.args) @mock.patch('time.sleep', return_value=None) @mock.patch('builtins.input', side_effect=['/rm Charlie', 'yes']) def test_unknown_account_when_removing_raises_se(self, *_: Any) -> None: self.assert_se("Error: Unknown contact 'Charlie'.", self.window.select_tx_window, *self.args) @mock.patch('time.sleep', return_value=None) @mock.patch('builtins.input', side_effect=['/rm Alice', 'no']) def test_abort_removal_of_contact_form_contact_selection(self, *_: Any) -> None: self.assert_se("Removal of contact aborted.", self.window.select_tx_window, *self.args) @mock.patch('time.sleep', return_value=None) @mock.patch('builtins.input', side_effect=['/rm Alice', 'yes']) def test_removing_pending_contact_from_contact_selection(self, *_: Any) -> None: self.assert_se("Removed contact 'Alice'.", self.window.select_tx_window, *self.args) @mock.patch('time.sleep', return_value=None) @mock.patch('builtins.input', side_effect=['/connect', b'a'.hex()]) def test_sending_onion_service_data_from_contact_selection( self, *_: Any) -> None: self.assertIsNone(self.window.select_tx_window(*self.args)) self.assertEqual(len(self.gateway.packets), 1) @mock.patch('time.sleep', return_value=None) @mock.patch('builtins.input', side_effect=['/help']) def test_invalid_command_raises_se(self, *_: Any) -> None: self.assert_se("Error: Invalid command.", self.window.select_tx_window, *self.args)
class TestPSK(TFCTestCase): def setUp(self) -> None: """Pre-test actions.""" self.unit_test_dir = cd_unit_test() self.contact_list = ContactList() self.settings = Settings(disable_gui_dialog=True) self.queues = gen_queue_dict() self.onion_service = OnionService() self.args = self.contact_list, self.settings, self.onion_service, self.queues def tearDown(self) -> None: """Post-test actions.""" cleanup(self.unit_test_dir) with ignored(OSError): os.remove( f"{self.onion_service.user_short_address}.psk - Give to {nick_to_short_address('Alice')}" ) tear_queues(self.queues) @mock.patch('builtins.input', side_effect=['/root/', '.', 'fc']) @mock.patch('time.sleep', return_value=None) @mock.patch('getpass.getpass', return_value='test_password') @mock.patch('src.transmitter.key_exchanges.ARGON2_PSK_MEMORY_COST', 1000) @mock.patch('src.transmitter.key_exchanges.ARGON2_PSK_TIME_COST', 1) def test_psk_creation(self, *_: Any) -> None: self.assertIsNone( create_pre_shared_key(nick_to_pub_key("Alice"), 'Alice', *self.args)) contact = self.contact_list.get_contact_by_pub_key( nick_to_pub_key("Alice")) self.assertEqual(contact.onion_pub_key, nick_to_pub_key("Alice")) self.assertEqual(contact.nick, 'Alice') self.assertEqual(contact.tx_fingerprint, bytes(FINGERPRINT_LENGTH)) self.assertEqual(contact.rx_fingerprint, bytes(FINGERPRINT_LENGTH)) self.assertEqual(contact.kex_status, KEX_STATUS_NO_RX_PSK) self.assertFalse(contact.log_messages) self.assertFalse(contact.file_reception) self.assertTrue(contact.notifications) cmd, account, tx_key, rx_key, tx_hek, rx_hek = self.queues[ KEY_MANAGEMENT_QUEUE].get() self.assertEqual(cmd, KDB_ADD_ENTRY_HEADER) self.assertEqual(account, nick_to_pub_key("Alice")) for key in [tx_key, rx_key, tx_hek, rx_hek]: self.assertIsInstance(key, bytes) self.assertEqual(len(key), SYMMETRIC_KEY_LENGTH) self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1) self.assertTrue( os.path.isfile( f"{self.onion_service.user_short_address}.psk - Give to {nick_to_short_address('Alice')}" )) @mock.patch('time.sleep', return_value=None) @mock.patch('getpass.getpass', side_effect=KeyboardInterrupt) def test_keyboard_interrupt_raises_soft_error(self, *_: Any) -> None: self.assert_se("PSK generation aborted.", create_pre_shared_key, nick_to_pub_key("Alice"), 'Alice', *self.args)
class TestRemoveContact(TFCTestCase): def setUp(self): self.o_input = builtins.input self.settings = Settings() self.master_key = MasterKey() self.queues = { KEY_MANAGEMENT_QUEUE: Queue(), COMMAND_PACKET_QUEUE: Queue() } self.contact_list = ContactList(nicks=['Alice']) self.group_list = GroupList(groups=['testgroup']) def tearDown(self): builtins.input = self.o_input for key in self.queues: while not self.queues[key].empty(): self.queues[key].get() time.sleep(0.1) self.queues[key].close() def test_contact_removal_during_traffic_masking_raises_fr(self): # Setup self.settings.session_traffic_masking = True # Test self.assertFR("Error: Command is disabled during traffic masking.", remove_contact, None, None, None, None, self.settings, None, self.master_key) def test_missing_account_raises_fr(self): # Setup user_input = UserInput('rm ') # Test self.assertFR("Error: No account specified.", remove_contact, user_input, None, None, None, self.settings, None, self.master_key) def test_user_abort_raises_fr(self): # Setup builtins.input = lambda _: 'No' user_input = UserInput('rm [email protected]') # Test self.assertFR("Removal of contact aborted.", remove_contact, user_input, None, None, None, self.settings, None, self.master_key) def test_successful_removal_of_contact(self): # Setup builtins.input = lambda _: 'Yes' user_input = UserInput('rm Alice') window = TxWindow( window_contacts=[self.contact_list.get_contact('Alice')], type=WIN_TYPE_CONTACT, uid='*****@*****.**') # Test for g in self.group_list: self.assertIsInstance(g, Group) self.assertTrue(g.has_member('*****@*****.**')) self.assertIsNone( remove_contact(user_input, window, self.contact_list, self.group_list, self.settings, self.queues, self.master_key)) time.sleep(0.1) self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 2) km_data = self.queues[KEY_MANAGEMENT_QUEUE].get() self.assertEqual(km_data, (KDB_REMOVE_ENTRY_HEADER, '*****@*****.**')) self.assertFalse(self.contact_list.has_contact('*****@*****.**')) for g in self.group_list: self.assertIsInstance(g, Group) self.assertFalse(g.has_member('*****@*****.**')) def test_successful_removal_of_last_member_of_active_group(self): # Setup builtins.input = lambda _: 'Yes' user_input = UserInput('rm Alice') window = TxWindow( window_contacts=[self.contact_list.get_contact('Alice')], type=WIN_TYPE_GROUP, name='testgroup') group = self.group_list.get_group('testgroup') group.members = [self.contact_list.get_contact('*****@*****.**')] # Test for g in self.group_list: self.assertIsInstance(g, Group) self.assertTrue(g.has_member('*****@*****.**')) self.assertEqual(len(group), 1) self.assertIsNone( remove_contact(user_input, window, self.contact_list, self.group_list, self.settings, self.queues, self.master_key)) time.sleep(0.1) for g in self.group_list: self.assertIsInstance(g, Group) self.assertFalse(g.has_member('*****@*****.**')) self.assertFalse(self.contact_list.has_contact('*****@*****.**')) self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 2) km_data = self.queues[KEY_MANAGEMENT_QUEUE].get() self.assertEqual(km_data, (KDB_REMOVE_ENTRY_HEADER, '*****@*****.**')) def test_no_contact_found_on_txm(self): # Setup builtins.input = lambda _: 'Yes' user_input = UserInput('rm [email protected]') contact_list = ContactList(nicks=['Bob']) window = TxWindow(window_contact=[contact_list.get_contact('Bob')], type=WIN_TYPE_GROUP) # Test self.assertIsNone( remove_contact(user_input, window, self.contact_list, self.group_list, self.settings, self.queues, self.master_key)) time.sleep(0.1) self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 2) command_packet, settings_ = self.queues[COMMAND_PACKET_QUEUE].get() self.assertIsInstance(command_packet, bytes) self.assertIsInstance(settings_, Settings)
def setUp(self) -> None: """Pre-test actions.""" self.contact_list = ContactList() self.settings = Settings() self.queues = gen_queue_dict() self.args = self.contact_list, self.settings, self.queues
class TestContactSetting(TFCTestCase): def setUp(self): self.c_queue = Queue() self.contact_list = ContactList(nicks=['Alice', 'Bob']) self.settings = Settings() self.group_list = GroupList(groups=['testgroup']) def tearDown(self): while not self.c_queue.empty(): self.c_queue.get() time.sleep(0.1) self.c_queue.close() def test_invalid_command_raises_fr(self): # Setup user_input = UserInput('loging on') # Test self.assertFR("Error: Invalid command.", contact_setting, user_input, None, None, None, None, None) def test_missing_parameter_raises_fr(self): # Setup user_input = UserInput('') # Test self.assertFR("Error: Invalid command.", contact_setting, user_input, None, None, None, None, None) def test_invalid_extra_parameter_raises_fr(self): # Setup user_input = UserInput('logging on al') # Test self.assertFR("Error: Invalid command.", contact_setting, user_input, None, None, None, None, None) def test_enable_logging_for_user(self): # Setup user_input = UserInput('logging on') contact = self.contact_list.get_contact('Alice') contact.log_messages = False window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact) # Test self.assertFalse(contact.log_messages) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) self.assertTrue(contact.log_messages) def test_enable_logging_for_user_during_traffic_masking(self): # Setup user_input = UserInput('logging on') contact = self.contact_list.get_contact('Alice') contact.log_messages = False window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact, log_messages=False) self.settings.session_traffic_masking = True # Test self.assertFalse(contact.log_messages) self.assertFalse(window.log_messages) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) self.assertEqual(self.c_queue.qsize(), 1) self.assertTrue(window.log_messages) self.assertTrue(contact.log_messages) def test_enable_logging_for_group(self): # Setup user_input = UserInput('logging on') group = self.group_list.get_group('testgroup') group.log_messages = False window = TxWindow(uid='testgroup', type=WIN_TYPE_GROUP, group=group, window_contacts=group.members) # Test self.assertFalse(group.log_messages) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) self.assertTrue(group.log_messages) def test_enable_logging_for_all_users(self): # Setup user_input = UserInput('logging on all') contact = self.contact_list.get_contact('*****@*****.**') window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) for c in self.contact_list: c.log_messages = False for g in self.group_list: g.log_messages = False # Test for c in self.contact_list: self.assertFalse(c.log_messages) for g in self.group_list: self.assertFalse(g.log_messages) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) for c in self.contact_list: self.assertTrue(c.log_messages) for g in self.group_list: self.assertTrue(g.log_messages) def test_disable_logging_for_user(self): # Setup user_input = UserInput('logging off') contact = self.contact_list.get_contact('Alice') contact.log_messages = True window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) # Test self.assertTrue(contact.log_messages) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) self.assertFalse(contact.log_messages) def test_disable_logging_for_group(self): # Setup user_input = UserInput('logging off') group = self.group_list.get_group('testgroup') group.log_messages = True window = TxWindow(uid='testgroup', type=WIN_TYPE_GROUP, group=group, window_contacts=group.members) # Test self.assertTrue(group.log_messages) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) self.assertFalse(group.log_messages) def test_disable_logging_for_all_users(self): # Setup user_input = UserInput('logging off all') contact = self.contact_list.get_contact('*****@*****.**') window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) for c in self.contact_list: c.log_messages = True for g in self.group_list: g.log_messages = True # Test for c in self.contact_list: self.assertTrue(c.log_messages) for g in self.group_list: self.assertTrue(g.log_messages) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) for c in self.contact_list: self.assertFalse(c.log_messages) for g in self.group_list: self.assertFalse(g.log_messages) def test_enable_file_reception_for_user(self): # Setup user_input = UserInput('store on') contact = self.contact_list.get_contact('Alice') contact.file_reception = False window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) # Test self.assertFalse(contact.file_reception) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) self.assertTrue(contact.file_reception) def test_enable_file_reception_for_group(self): # Setup user_input = UserInput('store on') group = self.group_list.get_group('testgroup') window = TxWindow(uid='testgroup', type=WIN_TYPE_GROUP, group=group, window_contacts=group.members) for m in group: m.file_reception = False # Test for m in group: self.assertFalse(m.file_reception) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) for m in group: self.assertTrue(m.file_reception) def test_enable_file_reception_for_all_users(self): # Setup user_input = UserInput('store on all') contact = self.contact_list.get_contact('*****@*****.**') window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) for c in self.contact_list: c.file_reception = False # Test for c in self.contact_list: self.assertFalse(c.file_reception) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) for c in self.contact_list: self.assertTrue(c.file_reception) def test_disable_file_reception_for_user(self): # Setup user_input = UserInput('store off') contact = self.contact_list.get_contact('Alice') contact.file_reception = True window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) # Test self.assertTrue(contact.file_reception) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) self.assertFalse(contact.file_reception) def test_disable_file_reception_for_group(self): # Setup user_input = UserInput('store off') group = self.group_list.get_group('testgroup') window = TxWindow(uid='testgroup', type=WIN_TYPE_GROUP, group=group, window_contacts=group.members) for m in group: m.file_reception = True # Test for m in group: self.assertTrue(m.file_reception) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) for m in group: self.assertFalse(m.file_reception) def test_disable_file_reception_for_all_users(self): # Setup user_input = UserInput('store off all') contact = self.contact_list.get_contact('*****@*****.**') window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) for c in self.contact_list: c.file_reception = True # Test for c in self.contact_list: self.assertTrue(c.file_reception) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) for c in self.contact_list: self.assertFalse(c.file_reception) def test_enable_notifications_for_user(self): # Setup user_input = UserInput('notify on') contact = self.contact_list.get_contact('Alice') contact.notifications = False window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact) # Test self.assertFalse(contact.notifications) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) self.assertTrue(contact.notifications) def test_enable_notifications_for_group(self): # Setup user_input = UserInput('notify on') group = self.group_list.get_group('testgroup') group.notifications = False window = TxWindow(uid='testgroup', type=WIN_TYPE_GROUP, group=group, window_contacts=group.members) # Test self.assertFalse(group.notifications) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) self.assertTrue(group.notifications) def test_enable_notifications_for_all_users(self): # Setup user_input = UserInput('notify on all') contact = self.contact_list.get_contact('*****@*****.**') window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) for c in self.contact_list: c.notifications = False for g in self.group_list: g.notifications = False # Test for c in self.contact_list: self.assertFalse(c.notifications) for g in self.group_list: self.assertFalse(g.notifications) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) for c in self.contact_list: self.assertTrue(c.notifications) for g in self.group_list: self.assertTrue(g.notifications) def test_disable_notifications_for_user(self): # Setup user_input = UserInput('notify off') contact = self.contact_list.get_contact('Alice') contact.notifications = True window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) # Test self.assertTrue(contact.notifications) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) self.assertFalse(contact.notifications) def test_disable_notifications_for_group(self): # Setup user_input = UserInput('notify off') group = self.group_list.get_group('testgroup') group.notifications = True window = TxWindow(uid='testgroup', type=WIN_TYPE_GROUP, group=group, window_contacts=group.members) # Test self.assertTrue(group.notifications) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) self.assertFalse(group.notifications) def test_disable_notifications_for_all_users(self): # Setup user_input = UserInput('notify off all') contact = self.contact_list.get_contact('*****@*****.**') window = TxWindow(uid='*****@*****.**', type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) for c in self.contact_list: c.notifications = True for g in self.group_list: g.notifications = True # Test for c in self.contact_list: self.assertTrue(c.notifications) for g in self.group_list: self.assertTrue(g.notifications) self.assertIsNone( contact_setting(user_input, window, self.contact_list, self.group_list, self.settings, self.c_queue)) time.sleep(0.1) for c in self.contact_list: self.assertFalse(c.notifications) for g in self.group_list: self.assertFalse(g.notifications)
def setUp(self) -> None: """Pre-test actions.""" self.contact_list = ContactList(nicks=['Alice']) self.lines = [nick_to_pub_key('Alice'), nick_to_pub_key('Bob')] self.group_name = 'test_group'
def setUp(self): self.c_queue = Queue() self.contact_list = ContactList(nicks=['Alice', 'Bob']) self.settings = Settings() self.group_list = GroupList(groups=['testgroup'])
class TestProcessMessagePacket(TFCTestCase): def setUp(self) -> None: """Pre-test actions.""" self.unit_test_dir = cd_unit_test() self.msg = ( "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean condimentum consectetur purus quis" " dapibus. Fusce venenatis lacus ut rhoncus faucibus. Cras sollicitudin commodo sapien, sed bibendu" "m velit maximus in. Aliquam ac metus risus. Sed cursus ornare luctus. Integer aliquet lectus id ma" "ssa blandit imperdiet. Ut sed massa eget quam facilisis rutrum. Mauris eget luctus nisl. Sed ut el" "it iaculis, faucibus lacus eget, sodales magna. Nunc sed commodo arcu. In hac habitasse platea dic" "tumst. Integer luctus aliquam justo, at vestibulum dolor iaculis ac. Etiam laoreet est eget odio r" "utrum, vel malesuada lorem rhoncus. Cras finibus in neque eu euismod. Nulla facilisi. Nunc nec ali" "quam quam, quis ullamcorper leo. Nunc egestas lectus eget est porttitor, in iaculis felis sceleris" "que. In sem elit, fringilla id viverra commodo, sagittis varius purus. Pellentesque rutrum loborti" "s neque a facilisis. Mauris id tortor placerat, aliquam dolor ac, venenatis arcu." ) self.ts = datetime.now() self.master_key = MasterKey() self.settings = Settings(log_file_masking=True) self.file_name = f'{DIR_USER_DATA}{self.settings.software_operation}_logs' self.contact_list = ContactList( nicks=['Alice', 'Bob', 'Charlie', LOCAL_ID]) self.key_list = KeyList(nicks=['Alice', 'Bob', 'Charlie', LOCAL_ID]) self.group_list = GroupList(groups=['test_group']) self.packet_list = PacketList(contact_list=self.contact_list, settings=self.settings) self.window_list = WindowList(contact_list=self.contact_list, settings=self.settings, group_list=self.group_list, packet_list=self.packet_list) self.group_id = group_name_to_group_id('test_group') self.file_keys = dict() self.log_file = f'{DIR_USER_DATA}{self.settings.software_operation}_logs' self.tfc_log_database = MessageLog(self.log_file, self.master_key.master_key) self.group_list.get_group('test_group').log_messages = True self.args = (self.window_list, self.packet_list, self.contact_list, self.key_list, self.group_list, self.settings, self.file_keys, self.tfc_log_database) ensure_dir(DIR_USER_DATA) def tearDown(self) -> None: """Post-test actions.""" cleanup(self.unit_test_dir) # Invalid packets @mock.patch('time.sleep', return_value=None) def test_invalid_origin_header_raises_se(self, _: Any) -> None: # Setup invalid_origin_header = b'e' packet = nick_to_pub_key( 'Alice') + invalid_origin_header + MESSAGE_LENGTH * b'm' # Test self.assert_se("Error: Received packet had an invalid origin-header.", process_message_packet, self.ts, packet, *self.args) @mock.patch('time.sleep', return_value=None) def test_masqueraded_command_raises_se(self, _: Any) -> None: for origin_header in [ORIGIN_USER_HEADER, ORIGIN_CONTACT_HEADER]: # Setup packet = LOCAL_PUBKEY + origin_header + MESSAGE_LENGTH * b'm' # Test self.assert_se( "Warning! Received packet masqueraded as a command.", process_message_packet, self.ts, packet, *self.args) # Private messages @mock.patch('time.sleep', return_value=None) def test_private_msg_from_contact(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( MESSAGE, self.msg, origin_header=ORIGIN_CONTACT_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice')) # Test for p in assembly_ct_list: self.assertIsNone(process_message_packet(self.ts, p, *self.args)) @mock.patch('time.sleep', return_value=None) def test_private_msg_from_user(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( MESSAGE, self.msg, origin_header=ORIGIN_USER_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice')) # Test for p in assembly_ct_list: self.assertIsNone(process_message_packet(self.ts, p, *self.args)) # Whispered messages @mock.patch('time.sleep', return_value=None) def test_whisper_msg_from_contact(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( MESSAGE, self.msg, origin_header=ORIGIN_CONTACT_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice'), whisper_header=bool_to_bytes(True)) # Test for p in assembly_ct_list[:-1]: self.assertIsNone(process_message_packet(self.ts, p, *self.args)) for p in assembly_ct_list[-1:]: self.assert_se("Whisper message complete.", process_message_packet, self.ts, p, *self.args) @mock.patch('time.sleep', return_value=None) def test_whisper_msg_from_user(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( MESSAGE, self.msg, origin_header=ORIGIN_USER_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice'), whisper_header=bool_to_bytes(True)) # Test for p in assembly_ct_list[:-1]: self.assertIsNone(process_message_packet(self.ts, p, *self.args)) for p in assembly_ct_list[-1:]: self.assert_se("Whisper message complete.", process_message_packet, self.ts, p, *self.args) @mock.patch('time.sleep', return_value=None) def test_empty_whisper_msg_from_user(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( MESSAGE, '', origin_header=ORIGIN_USER_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice'), whisper_header=bool_to_bytes(True)) # Test for p in assembly_ct_list[:-1]: self.assertIsNone(process_message_packet(self.ts, p, *self.args)) for p in assembly_ct_list[-1:]: self.assert_se("Whisper message complete.", process_message_packet, self.ts, p, *self.args) # File key messages @mock.patch('time.sleep', return_value=None) def test_user_origin_raises_se(self, _: Any) -> None: assembly_ct_list = assembly_packet_creator( MESSAGE, ' ', origin_header=ORIGIN_USER_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice'), message_header=FILE_KEY_HEADER) for p in assembly_ct_list[-1:]: self.assert_se("File key message from the user.", process_message_packet, self.ts, p, *self.args) @mock.patch('time.sleep', return_value=None) def test_invalid_file_key_data_raises_se(self, _: Any) -> None: assembly_ct_list = assembly_packet_creator( MESSAGE, ' ', origin_header=ORIGIN_CONTACT_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice'), message_header=FILE_KEY_HEADER) for p in assembly_ct_list[-1:]: self.assert_se("Error: Received an invalid file key message.", process_message_packet, self.ts, p, *self.args) @mock.patch('time.sleep', return_value=None) def test_too_large_file_key_data_raises_se(self, _: Any) -> None: assembly_ct_list = assembly_packet_creator( MESSAGE, base64.b85encode(BLAKE2_DIGEST_LENGTH * b'a' + SYMMETRIC_KEY_LENGTH * b'b' + b'a').decode(), origin_header=ORIGIN_CONTACT_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice'), message_header=FILE_KEY_HEADER) for p in assembly_ct_list[-1:]: self.assert_se("Error: Received an invalid file key message.", process_message_packet, self.ts, p, *self.args) @mock.patch('time.sleep', return_value=None) def test_valid_file_key_message(self, _: Any) -> None: assembly_ct_list = assembly_packet_creator( MESSAGE, base64.b85encode(BLAKE2_DIGEST_LENGTH * b'a' + SYMMETRIC_KEY_LENGTH * b'b').decode(), origin_header=ORIGIN_CONTACT_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice'), message_header=FILE_KEY_HEADER) for p in assembly_ct_list[-1:]: self.assert_se("Received file decryption key from Alice", process_message_packet, self.ts, p, *self.args) # Group messages @mock.patch('time.sleep', return_value=None) def test_invalid_message_header_raises_se(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( MESSAGE, 'test_message', origin_header=ORIGIN_CONTACT_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice'), message_header=b'Z') # Test self.assert_se("Error: Message from contact had an invalid header.", process_message_packet, self.ts, assembly_ct_list[0], *self.args) @mock.patch('time.sleep', return_value=None) def test_invalid_window_raises_se(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( MESSAGE, 'test_message', origin_header=ORIGIN_CONTACT_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice'), group_id=self.group_id) self.group_list.get_group( 'test_group').group_id = GROUP_ID_LENGTH * b'a' # Test self.assert_se("Error: Received message to an unknown group.", process_message_packet, self.ts, assembly_ct_list[0], *self.args) @mock.patch('time.sleep', return_value=None) def test_invalid_message_raises_se(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( MESSAGE, ' ', origin_header=ORIGIN_CONTACT_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice'), group_id=self.group_id, tamper_plaintext=True) # Test self.assert_se("Error: Received an invalid group message.", process_message_packet, self.ts, assembly_ct_list[0], *self.args) @mock.patch('time.sleep', return_value=None) def test_invalid_whisper_header_raises_se(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( MESSAGE, '', origin_header=ORIGIN_CONTACT_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice'), whisper_header=b'', message_header=b'') # Test self.assert_se( "Error: Message from contact had an invalid whisper header.", process_message_packet, self.ts, assembly_ct_list[0], *self.args) @mock.patch('time.sleep', return_value=None) def test_contact_not_in_group_raises_se(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( MESSAGE, 'test_message', origin_header=ORIGIN_CONTACT_HEADER, encrypt_packet=True, group_id=self.group_id, onion_pub_key=nick_to_pub_key('Charlie')) # Test self.assert_se("Error: Account is not a member of the group.", process_message_packet, self.ts, assembly_ct_list[0], *self.args) @mock.patch('time.sleep', return_value=None) def test_normal_group_msg_from_contact(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( MESSAGE, self.msg, origin_header=ORIGIN_CONTACT_HEADER, group_id=self.group_id, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice')) for p in assembly_ct_list: self.assertIsNone(process_message_packet(self.ts, p, *self.args)) @mock.patch('time.sleep', return_value=None) def test_normal_group_msg_from_user(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( MESSAGE, self.msg, origin_header=ORIGIN_USER_HEADER, group_id=self.group_id, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice')) for p in assembly_ct_list: self.assertIsNone(process_message_packet(self.ts, p, *self.args)) # Files @mock.patch('time.sleep', return_value=None) def test_file(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( FILE, origin_header=ORIGIN_CONTACT_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice')) # Test for p in assembly_ct_list[:-1]: self.assertIsNone(process_message_packet(self.ts, p, *self.args)) for p in assembly_ct_list[-1:]: self.assert_se("File storage complete.", process_message_packet, self.ts, p, *self.args) @mock.patch('time.sleep', return_value=None) def test_file_when_reception_is_disabled(self, _: Any) -> None: # Setup assembly_ct_list = assembly_packet_creator( FILE, origin_header=ORIGIN_CONTACT_HEADER, encrypt_packet=True, onion_pub_key=nick_to_pub_key('Alice')) self.contact_list.get_contact_by_pub_key( nick_to_pub_key('Alice')).file_reception = False # Test self.assert_se( "Alert! File transmission from Alice but reception is disabled.", process_message_packet, self.ts, assembly_ct_list[0], *self.args)
class TestAddNewContact(TFCTestCase): def setUp(self): self.o_getpass = getpass.getpass self.contact_list = ContactList() self.group_list = GroupList() self.settings = Settings(disable_gui_dialog=True) self.queues = { COMMAND_PACKET_QUEUE: Queue(), NH_PACKET_QUEUE: Queue(), KEY_MANAGEMENT_QUEUE: Queue() } def tearDown(self): getpass.getpass = self.o_getpass with ignored(OSError): os.remove('[email protected] - Give to [email protected]') for key in self.queues: while not self.queues[key].empty(): self.queues[key].get() time.sleep(0.1) self.queues[key].close() def test_adding_new_contact_during_traffic_masking_raises_fr(self): # Setup self.settings.session_traffic_masking = True # Test self.assertFR("Error: Command is disabled during traffic masking.", add_new_contact, self.contact_list, self.group_list, self.settings, self.queues) def test_contact_list_full_raises_fr(self): # Setup self.contact_list = ContactList( nicks=['contact_{}'.format(n) for n in range(20)]) # Test self.assertFR("Error: TFC settings only allow 20 accounts.", add_new_contact, self.contact_list, self.group_list, self.settings, self.queues) def test_default_nick_x25519_kex(self): # Setup input_list = [ '*****@*****.**', '*****@*****.**', '', '', '5JJwZE46Eic9B8sKJ8Qocyxa8ytUJSfcqRo7Hr5ES7YgFGeJjCJ', 'Yes' ] gen = iter(input_list) builtins.input = lambda _: str(next(gen)) # Test self.assertIsNone( add_new_contact(self.contact_list, self.group_list, self.settings, self.queues)) contact = self.contact_list.get_contact('*****@*****.**') self.assertEqual(contact.nick, 'Alice') self.assertNotEqual(contact.tx_fingerprint, bytes( FINGERPRINT_LEN)) # Indicates that PSK function was not called def test_standard_nick_psk_kex(self): # Setup getpass.getpass = lambda _: 'test_password' input_list = [ '*****@*****.**', '*****@*****.**', 'Alice_', 'psk', '.' ] gen = iter(input_list) builtins.input = lambda _: str(next(gen)) # Test self.assertIsNone( add_new_contact(self.contact_list, self.group_list, self.settings, self.queues)) contact = self.contact_list.get_contact('*****@*****.**') self.assertEqual(contact.nick, 'Alice_') self.assertEqual( contact.tx_fingerprint, bytes(FINGERPRINT_LEN)) # Indicates that PSK function was called
def setUp(self): self.contact_list = ContactList(nicks=['Alice', 'Bob']) self.group_list = GroupList(groups=['test_group'])
class TestContactSetting(TFCTestCase): def setUp(self): """Pre-test actions.""" self.contact_list = ContactList(nicks=['Alice', 'Bob']) self.group_list = GroupList(groups=['test_group']) self.settings = Settings() self.queues = gen_queue_dict() self.pub_key = nick_to_pub_key("Alice") self.args = self.contact_list, self.group_list, self.settings, self.queues def tearDown(self): """Post-test actions.""" tear_queues(self.queues) def test_invalid_command_raises_fr(self): self.assert_fr("Error: Invalid command.", contact_setting, UserInput('loging on'), None, *self.args) def test_missing_parameter_raises_fr(self): self.assert_fr("Error: Invalid command.", contact_setting, UserInput(''), None, *self.args) def test_invalid_extra_parameter_raises_fr(self): self.assert_fr("Error: Invalid command.", contact_setting, UserInput('logging on al'), None, *self.args) def test_enable_logging_for_user(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick('Alice') contact.log_messages = False window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact) # Test self.assertFalse(contact.log_messages) self.assertIsNone(contact_setting(UserInput('logging on'), window, *self.args)) self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1) self.assertEqual(self.queues[LOG_SETTING_QUEUE].qsize(), 0) self.assertTrue(contact.log_messages) def test_enable_logging_for_user_during_traffic_masking(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick('Alice') contact.log_messages = False window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact, log_messages=False) self.settings.traffic_masking = True # Test self.assertFalse(contact.log_messages) self.assertFalse(window.log_messages) self.assertIsNone(contact_setting(UserInput('logging on'), window, *self.args)) self.assertEqual(self.queues[TM_COMMAND_PACKET_QUEUE].qsize(), 1) self.assertTrue(self.queues[LOG_SETTING_QUEUE].get()) self.assertTrue(window.log_messages) self.assertTrue(contact.log_messages) def test_enable_logging_for_group(self): # Setup group = self.group_list.get_group('test_group') group.log_messages = False window = TxWindow(uid=group_name_to_group_id('test_group'), type=WIN_TYPE_GROUP, group=group, window_contacts=group.members) # Test self.assertFalse(group.log_messages) self.assertIsNone(contact_setting(UserInput('logging on'), window, *self.args)) self.assertTrue(group.log_messages) def test_enable_logging_for_all_users(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick("Alice") window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) for c in self.contact_list: c.log_messages = False for g in self.group_list: g.log_messages = False # Test for c in self.contact_list: self.assertFalse(c.log_messages) for g in self.group_list: self.assertFalse(g.log_messages) self.assertIsNone(contact_setting(UserInput('logging on all'), window, *self.args)) for c in self.contact_list: self.assertTrue(c.log_messages) for g in self.group_list: self.assertTrue(g.log_messages) def test_disable_logging_for_user(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick('Alice') contact.log_messages = True window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) # Test self.assertTrue(contact.log_messages) self.assertIsNone(contact_setting(UserInput('logging off'), window, *self.args)) self.assertFalse(contact.log_messages) def test_disable_logging_for_group(self): # Setup group = self.group_list.get_group('test_group') group.log_messages = True window = TxWindow(uid=group_name_to_group_id('test_group'), type=WIN_TYPE_GROUP, group=group, window_contacts=group.members) # Test self.assertTrue(group.log_messages) self.assertIsNone(contact_setting(UserInput('logging off'), window, *self.args)) self.assertFalse(group.log_messages) def test_disable_logging_for_all_users(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick("Alice") window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) for c in self.contact_list: c.log_messages = True for g in self.group_list: g.log_messages = True # Test for c in self.contact_list: self.assertTrue(c.log_messages) for g in self.group_list: self.assertTrue(g.log_messages) self.assertIsNone(contact_setting(UserInput('logging off all'), window, *self.args)) for c in self.contact_list: self.assertFalse(c.log_messages) for g in self.group_list: self.assertFalse(g.log_messages) def test_enable_file_reception_for_user(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick('Alice') contact.file_reception = False window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) # Test self.assertFalse(contact.file_reception) self.assertIsNone(contact_setting(UserInput('store on'), window, *self.args)) self.assertTrue(contact.file_reception) def test_enable_file_reception_for_group(self): # Setup group = self.group_list.get_group('test_group') window = TxWindow(uid=group_name_to_group_id('test_group'), type=WIN_TYPE_GROUP, group=group, window_contacts=group.members) for m in group: m.file_reception = False # Test for m in group: self.assertFalse(m.file_reception) self.assertIsNone(contact_setting(UserInput('store on'), window, *self.args)) for m in group: self.assertTrue(m.file_reception) def test_enable_file_reception_for_all_users(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick("Alice") window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) for c in self.contact_list: c.file_reception = False # Test for c in self.contact_list: self.assertFalse(c.file_reception) self.assertIsNone(contact_setting(UserInput('store on all'), window, *self.args)) for c in self.contact_list: self.assertTrue(c.file_reception) def test_disable_file_reception_for_user(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick('Alice') contact.file_reception = True window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) # Test self.assertTrue(contact.file_reception) self.assertIsNone(contact_setting(UserInput('store off'), window, *self.args)) self.assertFalse(contact.file_reception) def test_disable_file_reception_for_group(self): # Setup group = self.group_list.get_group('test_group') window = TxWindow(uid=group_name_to_group_id('test_group'), type=WIN_TYPE_GROUP, group=group, window_contacts=group.members) for m in group: m.file_reception = True # Test for m in group: self.assertTrue(m.file_reception) self.assertIsNone(contact_setting(UserInput('store off'), window, *self.args)) for m in group: self.assertFalse(m.file_reception) def test_disable_file_reception_for_all_users(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick("Alice") window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) for c in self.contact_list: c.file_reception = True # Test for c in self.contact_list: self.assertTrue(c.file_reception) self.assertIsNone(contact_setting(UserInput('store off all'), window, *self.args)) for c in self.contact_list: self.assertFalse(c.file_reception) def test_enable_notifications_for_user(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick('Alice') contact.notifications = False window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact) # Test self.assertFalse(contact.notifications) self.assertIsNone(contact_setting(UserInput('notify on'), window, *self.args)) self.assertTrue(contact.notifications) def test_enable_notifications_for_group(self): # Setup user_input = UserInput('notify on') group = self.group_list.get_group('test_group') group.notifications = False window = TxWindow(uid=group_name_to_group_id('test_group'), type=WIN_TYPE_GROUP, group=group, window_contacts=group.members) # Test self.assertFalse(group.notifications) self.assertIsNone(contact_setting(user_input, window, *self.args)) self.assertTrue(group.notifications) def test_enable_notifications_for_all_users(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick("Alice") window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) for c in self.contact_list: c.notifications = False for g in self.group_list: g.notifications = False # Test for c in self.contact_list: self.assertFalse(c.notifications) for g in self.group_list: self.assertFalse(g.notifications) self.assertIsNone(contact_setting(UserInput('notify on all'), window, *self.args)) for c in self.contact_list: self.assertTrue(c.notifications) for g in self.group_list: self.assertTrue(g.notifications) def test_disable_notifications_for_user(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick('Alice') contact.notifications = True window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) # Test self.assertTrue(contact.notifications) self.assertIsNone(contact_setting(UserInput('notify off'), window, *self.args)) self.assertFalse(contact.notifications) def test_disable_notifications_for_group(self): # Setup group = self.group_list.get_group('test_group') group.notifications = True window = TxWindow(uid=group_name_to_group_id('test_group'), type=WIN_TYPE_GROUP, group=group, window_contacts=group.members) # Test self.assertTrue(group.notifications) self.assertIsNone(contact_setting(UserInput('notify off'), window, *self.args)) self.assertFalse(group.notifications) def test_disable_notifications_for_all_users(self): # Setup contact = self.contact_list.get_contact_by_address_or_nick("Alice") window = TxWindow(uid=self.pub_key, type=WIN_TYPE_CONTACT, contact=contact, window_contacts=[contact]) for c in self.contact_list: c.notifications = True for g in self.group_list: g.notifications = True # Test for c in self.contact_list: self.assertTrue(c.notifications) for g in self.group_list: self.assertTrue(g.notifications) self.assertIsNone(contact_setting(UserInput('notify off all'), window, *self.args)) for c in self.contact_list: self.assertFalse(c.notifications) for g in self.group_list: self.assertFalse(g.notifications)