<s> from corehq . apps . domain . models import Domain <EOL> from corehq . apps . sms . api import send_sms , incoming <EOL> from corehq . apps . sms . models import SMS , QueuedSMS <EOL> from corehq . apps . sms . tasks import process_sms <EOL> from corehq . apps . sms . tests . util import BaseSMSTest , setup_default_sms_test_backend <EOL> from corehq . apps . smsbillables . models import SmsBillable <EOL> from corehq . apps . users . models import CommCareUser <EOL> from datetime import datetime , timedelta <EOL> from django . conf import settings <EOL> from django . test . utils import override_settings <EOL> from mock import Mock , patch <EOL> def patch_datetime_api ( timestamp ) : <EOL> return patch ( '<STR_LIT>' , new = Mock ( return_value = timestamp ) ) <EOL> def patch_datetime_tasks ( timestamp ) : <EOL> return patch ( '<STR_LIT>' , new = Mock ( return_value = timestamp ) ) <EOL> def patch_successful_send ( ) : <EOL> return patch ( '<STR_LIT>' ) <EOL> def patch_failed_send ( ) : <EOL> return patch ( <EOL> '<STR_LIT>' , <EOL> new = Mock ( side_effect = Exception ) <EOL> ) <EOL> def patch_error_send ( ) : <EOL> def set_error ( msg , * args , ** kwargs ) : <EOL> msg . set_system_error ( '<STR_LIT>' ) <EOL> return patch ( <EOL> '<STR_LIT>' , <EOL> new = Mock ( side_effect = set_error ) <EOL> ) <EOL> @ patch ( '<STR_LIT>' , autospec = True ) <EOL> @ patch ( '<STR_LIT>' , autospec = True ) <EOL> @ override_settings ( SMS_QUEUE_ENABLED = True ) <EOL> class QueueingTestCase ( BaseSMSTest ) : <EOL> def setUp ( self ) : <EOL> super ( QueueingTestCase , self ) . setUp ( ) <EOL> self . domain = '<STR_LIT>' <EOL> self . domain_obj = Domain ( name = self . domain ) <EOL> self . domain_obj . save ( ) <EOL> self . create_account_and_subscription ( self . domain ) <EOL> self . domain_obj = Domain . get ( self . domain_obj . _id ) <EOL> self . backend , self . backend_mapping = setup_default_sms_test_backend ( ) <EOL> self . contact = CommCareUser . create ( self . domain , '<STR_LIT>' , '<STR_LIT:abc>' , phone_number = '<STR_LIT>' ) <EOL> self . contact . save_verified_number ( self . domain , '<STR_LIT>' , True ) <EOL> SmsBillable . objects . filter ( domain = self . domain ) . delete ( ) <EOL> QueuedSMS . objects . all ( ) . delete ( ) <EOL> SMS . objects . filter ( domain = self . domain ) . delete ( ) <EOL> def tearDown ( self ) : <EOL> self . contact . delete_verified_number ( '<STR_LIT>' ) <EOL> self . contact . delete ( ) <EOL> self . backend . delete ( ) <EOL> self . backend_mapping . delete ( ) <EOL> SmsBillable . objects . filter ( domain = self . domain ) . delete ( ) <EOL> QueuedSMS . objects . all ( ) . delete ( ) <EOL> SMS . objects . filter ( domain = self . domain ) . delete ( ) <EOL> self . domain_obj . delete ( ) <EOL> super ( QueueingTestCase , self ) . tearDown ( ) <EOL> @ property <EOL> def queued_sms_count ( self ) : <EOL> return QueuedSMS . objects . count ( ) <EOL> @ property <EOL> def reporting_sms_count ( self ) : <EOL> return SMS . objects . filter ( domain = self . domain ) . count ( ) <EOL> def get_queued_sms ( self ) : <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:1> ) <EOL> return QueuedSMS . objects . all ( ) [ <NUM_LIT:0> ] <EOL> def get_reporting_sms ( self ) : <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:1> ) <EOL> return SMS . objects . filter ( domain = self . domain ) [ <NUM_LIT:0> ] <EOL> def assertBillableExists ( self , msg_id , count = <NUM_LIT:1> ) : <EOL> self . assertEqual ( SmsBillable . objects . filter ( log_id = msg_id ) . count ( ) , count ) <EOL> def assertBillableDoesNotExist ( self , msg_id ) : <EOL> self . assertEqual ( SmsBillable . objects . filter ( log_id = msg_id ) . count ( ) , <NUM_LIT:0> ) <EOL> def test_outgoing ( self , process_sms_delay_mock , enqueue_directly_mock ) : <EOL> send_sms ( self . domain , None , '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . assertEqual ( enqueue_directly_mock . call_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:0> ) <EOL> queued_sms = self . get_queued_sms ( ) <EOL> self . assertEqual ( queued_sms . domain , self . domain ) <EOL> self . assertEqual ( queued_sms . phone_number , '<STR_LIT>' ) <EOL> self . assertEqual ( queued_sms . text , '<STR_LIT>' ) <EOL> self . assertEqual ( queued_sms . processed , False ) <EOL> self . assertEqual ( queued_sms . error , False ) <EOL> couch_id = queued_sms . couch_id <EOL> self . assertIsNotNone ( couch_id ) <EOL> with patch_successful_send ( ) as send_mock : <EOL> process_sms ( queued_sms . pk ) <EOL> self . assertEqual ( send_mock . call_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:0> ) <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:1> ) <EOL> reporting_sms = self . get_reporting_sms ( ) <EOL> self . assertEqual ( reporting_sms . domain , self . domain ) <EOL> self . assertEqual ( reporting_sms . phone_number , '<STR_LIT>' ) <EOL> self . assertEqual ( reporting_sms . text , '<STR_LIT>' ) <EOL> self . assertEqual ( reporting_sms . processed , True ) <EOL> self . assertEqual ( reporting_sms . error , False ) <EOL> self . assertEqual ( reporting_sms . couch_id , couch_id ) <EOL> self . assertEqual ( reporting_sms . backend_api , self . backend . get_api_id ( ) ) <EOL> self . assertEqual ( reporting_sms . backend_id , self . backend . couch_id ) <EOL> self . assertEqual ( process_sms_delay_mock . call_count , <NUM_LIT:0> ) <EOL> self . assertBillableExists ( couch_id ) <EOL> def test_outgoing_failure ( self , process_sms_delay_mock , enqueue_directly_mock ) : <EOL> timestamp = datetime ( <NUM_LIT> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:12> , <NUM_LIT:0> ) <EOL> with patch_datetime_api ( timestamp ) : <EOL> send_sms ( self . domain , None , '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . assertEqual ( enqueue_directly_mock . call_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:0> ) <EOL> for i in range ( settings . SMS_QUEUE_MAX_PROCESSING_ATTEMPTS ) : <EOL> queued_sms = self . get_queued_sms ( ) <EOL> self . assertEqual ( queued_sms . domain , self . domain ) <EOL> self . assertEqual ( queued_sms . phone_number , '<STR_LIT>' ) <EOL> self . assertEqual ( queued_sms . text , '<STR_LIT>' ) <EOL> self . assertEqual ( queued_sms . datetime_to_process , timestamp ) <EOL> self . assertEqual ( queued_sms . processed , False ) <EOL> self . assertEqual ( queued_sms . error , False ) <EOL> self . assertEqual ( queued_sms . num_processing_attempts , i ) <EOL> with patch_failed_send ( ) as send_mock , patch_datetime_tasks ( timestamp + timedelta ( seconds = <NUM_LIT:1> ) ) : <EOL> process_sms ( queued_sms . pk ) <EOL> self . assertEqual ( process_sms_delay_mock . call_count , <NUM_LIT:0> ) <EOL> self . assertBillableDoesNotExist ( queued_sms . couch_id ) <EOL> self . assertEqual ( send_mock . call_count , <NUM_LIT:1> ) <EOL> if i < ( settings . SMS_QUEUE_MAX_PROCESSING_ATTEMPTS - <NUM_LIT:1> ) : <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:0> ) <EOL> timestamp += timedelta ( minutes = settings . SMS_QUEUE_REPROCESS_INTERVAL ) <EOL> else : <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:0> ) <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:1> ) <EOL> reporting_sms = self . get_reporting_sms ( ) <EOL> self . assertEqual ( reporting_sms . domain , self . domain ) <EOL> self . assertEqual ( reporting_sms . phone_number , '<STR_LIT>' ) <EOL> self . assertEqual ( reporting_sms . text , '<STR_LIT>' ) <EOL> self . assertEqual ( reporting_sms . processed , False ) <EOL> self . assertEqual ( reporting_sms . error , True ) <EOL> self . assertEqual ( reporting_sms . num_processing_attempts , settings . SMS_QUEUE_MAX_PROCESSING_ATTEMPTS ) <EOL> self . assertBillableDoesNotExist ( reporting_sms . couch_id ) <EOL> def test_outgoing_failure_recovery ( self , process_sms_delay_mock , enqueue_directly_mock ) : <EOL> timestamp = datetime ( <NUM_LIT> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:12> , <NUM_LIT:0> ) <EOL> with patch_datetime_api ( timestamp ) : <EOL> send_sms ( self . domain , None , '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . assertEqual ( enqueue_directly_mock . call_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:0> ) <EOL> queued_sms = self . get_queued_sms ( ) <EOL> self . assertEqual ( queued_sms . datetime_to_process , timestamp ) <EOL> self . assertEqual ( queued_sms . processed , False ) <EOL> self . assertEqual ( queued_sms . error , False ) <EOL> self . assertEqual ( queued_sms . num_processing_attempts , <NUM_LIT:0> ) <EOL> with patch_failed_send ( ) as send_mock , patch_datetime_tasks ( timestamp + timedelta ( seconds = <NUM_LIT:1> ) ) : <EOL> process_sms ( queued_sms . pk ) <EOL> self . assertEqual ( process_sms_delay_mock . call_count , <NUM_LIT:0> ) <EOL> self . assertBillableDoesNotExist ( queued_sms . couch_id ) <EOL> self . assertEqual ( send_mock . call_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:0> ) <EOL> timestamp += timedelta ( minutes = settings . SMS_QUEUE_REPROCESS_INTERVAL ) <EOL> queued_sms = self . get_queued_sms ( ) <EOL> self . assertEqual ( queued_sms . datetime_to_process , timestamp ) <EOL> self . assertEqual ( queued_sms . processed , False ) <EOL> self . assertEqual ( queued_sms . error , False ) <EOL> self . assertEqual ( queued_sms . num_processing_attempts , <NUM_LIT:1> ) <EOL> with patch_successful_send ( ) as send_mock , patch_datetime_tasks ( timestamp + timedelta ( seconds = <NUM_LIT:1> ) ) : <EOL> process_sms ( queued_sms . pk ) <EOL> self . assertEqual ( send_mock . call_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:0> ) <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:1> ) <EOL> reporting_sms = self . get_reporting_sms ( ) <EOL> self . assertEqual ( reporting_sms . processed , True ) <EOL> self . assertEqual ( reporting_sms . error , False ) <EOL> self . assertEqual ( reporting_sms . num_processing_attempts , <NUM_LIT:2> ) <EOL> self . assertEqual ( process_sms_delay_mock . call_count , <NUM_LIT:0> ) <EOL> self . assertBillableExists ( reporting_sms . couch_id ) <EOL> def test_outgoing_with_error ( self , process_sms_delay_mock , enqueue_directly_mock ) : <EOL> send_sms ( self . domain , None , '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . assertEqual ( enqueue_directly_mock . call_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:0> ) <EOL> queued_sms = self . get_queued_sms ( ) <EOL> self . assertEqual ( queued_sms . processed , False ) <EOL> self . assertEqual ( queued_sms . error , False ) <EOL> couch_id = queued_sms . couch_id <EOL> self . assertIsNotNone ( couch_id ) <EOL> with patch_error_send ( ) as send_mock : <EOL> process_sms ( queued_sms . pk ) <EOL> self . assertEqual ( send_mock . call_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:0> ) <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:1> ) <EOL> reporting_sms = self . get_reporting_sms ( ) <EOL> self . assertEqual ( reporting_sms . processed , False ) <EOL> self . assertEqual ( reporting_sms . error , True ) <EOL> self . assertEqual ( reporting_sms . couch_id , couch_id ) <EOL> self . assertEqual ( reporting_sms . backend_api , self . backend . get_api_id ( ) ) <EOL> self . assertEqual ( reporting_sms . backend_id , self . backend . couch_id ) <EOL> self . assertEqual ( process_sms_delay_mock . call_count , <NUM_LIT:0> ) <EOL> self . assertBillableDoesNotExist ( couch_id ) <EOL> def test_incoming ( self , process_sms_delay_mock , enqueue_directly_mock ) : <EOL> incoming ( '<STR_LIT>' , '<STR_LIT>' , self . backend . get_api_id ( ) ) <EOL> self . assertEqual ( enqueue_directly_mock . call_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:1> ) <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:0> ) <EOL> queued_sms = self . get_queued_sms ( ) <EOL> self . assertIsNone ( queued_sms . domain ) <EOL> self . assertIsNone ( queued_sms . couch_recipient_doc_type ) <EOL> self . assertIsNone ( queued_sms . couch_recipient ) <EOL> self . assertEqual ( queued_sms . phone_number , '<STR_LIT>' ) <EOL> self . assertEqual ( queued_sms . text , '<STR_LIT>' ) <EOL> self . assertEqual ( queued_sms . processed , False ) <EOL> self . assertEqual ( queued_sms . error , False ) <EOL> self . assertEqual ( queued_sms . backend_api , self . backend . get_api_id ( ) ) <EOL> couch_id = queued_sms . couch_id <EOL> self . assertIsNotNone ( couch_id ) <EOL> self . assertBillableDoesNotExist ( couch_id ) <EOL> process_sms ( queued_sms . pk ) <EOL> self . assertEqual ( self . queued_sms_count , <NUM_LIT:0> ) <EOL> self . assertEqual ( self . reporting_sms_count , <NUM_LIT:1> ) <EOL> reporting_sms = self . get_reporting_sms ( ) <EOL> self . assertEqual ( reporting_sms . domain , self . domain ) <EOL> self . assertEqual ( reporting_sms . couch_recipient_doc_type , self . contact . doc_type ) <EOL> self . assertEqual ( reporting_sms . couch_recipient , self . contact . get_id ) <EOL> self . assertEqual ( reporting_sms . phone_number , '<STR_LIT>' ) <EOL> self . assertEqual ( reporting_sms . text , '<STR_LIT>' ) <EOL> self . assertEqual ( reporting_sms . processed , True ) <EOL> self . assertEqual ( reporting_sms . error , False ) <EOL> self . assertEqual ( reporting_sms . backend_api , self . backend . get_api_id ( ) ) <EOL> self . assertEqual ( reporting_sms . couch_id , couch_id ) <EOL> self . assertBillableExists ( couch_id ) </s>
