import tempfile from unittest.mock import Mock, patch from django.test import TestCase from core.clients import transport class SignalUnlinkFallbackTests(TestCase): def test_signal_wipe_uses_project_signal_cli_config_dir(self): with tempfile.TemporaryDirectory() as tmpdir: signal_root = os.path.join(tmpdir, "signal-cli-config") os.makedirs(signal_root, exist_ok=True) account_dir = os.path.join(signal_root, "account-data") os.makedirs(account_dir, exist_ok=True) keep_file = os.path.join(signal_root, "jsonrpc2.yml") with open(keep_file, "w", encoding="utf-8") as handle: handle.write("jsonrpc") data_file = os.path.join(account_dir, "state.db") with open(data_file, "w", encoding="utf-8") as handle: handle.write("state") with patch.object(transport.settings, "BASE_DIR", tmpdir): result = transport._wipe_signal_cli_local_state() self.assertTrue(result) self.assertTrue(os.path.exists(keep_file)) self.assertFalse(os.path.exists(account_dir)) @patch("requests.get") def test_signal_list_accounts_uses_fast_timeout(self, mock_get): ok_response = Mock() ok_response.ok = True ok_response.text = "[]" mock_get.return_value = ok_response result = transport.list_accounts("signal") self.assertEqual([], result) mock_get.assert_called_once() _, kwargs = mock_get.call_args self.assertEqual(5, int(kwargs.get("timeout") or 0)) @patch("core.clients.transport._wipe_signal_cli_local_state") @patch("requests.delete") def test_signal_unlink_uses_rest_delete_when_available( self, mock_delete, mock_wipe, ): ok_response = Mock() ok_response.ok = True mock_delete.return_value = ok_response result = transport.unlink_account("signal", "+447700900000") self.assertTrue(result) self.assertTrue(mock_delete.called) mock_wipe.assert_not_called() @patch("core.clients.transport._wipe_signal_cli_local_state") @patch("requests.delete") def test_signal_unlink_falls_back_to_local_wipe( self, mock_delete, mock_wipe, ): bad_response = Mock() bad_response.ok = False mock_delete.return_value = bad_response mock_wipe.return_value = True result = transport.unlink_account("signal", "+447700900000") self.assertTrue(result) self.assertEqual(2, mock_delete.call_count) mock_wipe.assert_called_once() @patch("core.clients.transport.list_accounts") @patch("core.clients.transport._wipe_signal_cli_local_state") @patch("requests.delete") def test_signal_unlink_returns_false_when_account_still_listed_after_wipe( self, mock_delete, mock_wipe, mock_list_accounts, ): bad_response = Mock() bad_response.ok = False mock_delete.return_value = bad_response mock_wipe.return_value = True mock_list_accounts.return_value = ["+447700900000"] result = transport.unlink_account("signal", "+447700900000") self.assertFalse(result) self.assertEqual(2, mock_delete.call_count) mock_wipe.assert_called_once() mock_list_accounts.assert_called_once_with("signal")