def run_handlers(self): handler = self.ussd_request.session['_ussd_state']['next_screen'] \ if self.ussd_request.session.get('_ussd_state', {}).get('next_screen') \ else "initial_screen" ussd_response = (self.ussd_request, handler) if handler != "initial_screen": # get start time start_time = utilities.string_to_datetime( self.ussd_request.session["ussd_interaction"][-1] ["start_time"]) end_time = datetime.datetime.now() # Report in milliseconds duration = (end_time - start_time).total_seconds() * 1000 self.ussd_request.session["ussd_interaction"][-1].update({ "input": self.ussd_request.input, "end_time": utilities.datetime_to_string(end_time), "duration": duration }) # Handle any forwarded Requests; loop until a Response is # eventually returned. while not isinstance(ussd_response, UssdResponse): self.ussd_request, handler = ussd_response screen_content = self.ussd_request.get_screens(handler) screen_type = 'initial_screen' \ if handler == "initial_screen" and \ isinstance(screen_content, str) \ else screen_content['type'] ussd_response = _registered_ussd_handlers[screen_type]( self.ussd_request, handler, screen_content, initial_screen=self.initial_screen, logger=self.logger).handle() self.ussd_request.session['_ussd_state']['next_screen'] = handler self.ussd_request.session['ussd_interaction'].append({ "screen_name": handler, "screen_text": str(ussd_response), "input": self.ussd_request.input, "start_time": utilities.datetime_to_string(datetime.datetime.now()) }) # Attach session to outgoing response ussd_response.session = self.ussd_request.session return ussd_response
def ussd_dispatcher(self, ussd_request): # Clear input and initialize session if we are starting up if '_ussd_state' not in ussd_request.session: ussd_request.input = '' ussd_request.session['_ussd_state'] = {'next_screen': ''} ussd_request.session['ussd_interaction'] = [] ussd_request.session['posted'] = False ussd_request.session['submit_data'] = {} ussd_request.session['session_id'] = ussd_request.session_id ussd_request.session['phone_number'] = ussd_request.phone_number # update ussd_request variable to session and template variables # to be used later for jinja2 evaluation ussd_request.session.update(ussd_request.all_variables()) # for backward compatibility # there are some jinja template using ussd_request # eg. {{ussd_request.session_id}} ussd_request.session.update( {"ussd_request": ussd_request.all_variables()} ) self.logger.debug('gateway_request', text=ussd_request.input) # Invoke handlers ussd_response = self.run_handlers(ussd_request) ussd_request.session[defaults.last_update] = \ utilities.datetime_to_string(datetime.now()) # Save session ussd_request.session.save() self.logger.debug('gateway_response', text=ussd_response.dumps(), input="{redacted}") return ussd_response
def test_session_expiry_using_inactivity(self): # Test session expiry is using last time session was updated phone_number = '201' req = self._create_ussd_request(phone_number) time.sleep(0.8) # confirm session_id hasn't changed self.assertEqual(req.session_id, self._create_ussd_request(phone_number).session_id) # make a change in session req = self._create_ussd_request(phone_number) req.session['name'] = 'mwas' req.session[ussd_airflow_variables.last_update] = datetime_to_string( datetime.now()) req.session.save() time.sleep(0.8) # confirm even after the session was created 1.6 sec ago hasn't # been closed self.assertEqual( req.session['name'], self._create_ussd_request(phone_number).session['name']) time.sleep(3) # test now the session has been closed self.assertIsNone( self._create_ussd_request(phone_number).session.get('name'))
def test_session_expiry_using_inactivity(self): # Test session expiry is using last time session was updated phone_number = '201' req = self._create_ussd_request(phone_number) time.sleep(0.8) # confirm session_id hasn't changed self.assertEqual( req.session_id, self._create_ussd_request(phone_number).session_id ) # make a change in session req = self._create_ussd_request(phone_number) req.session['name'] = 'mwas' req.session[ussd_airflow_variables.last_update] = datetime_to_string( datetime.now()) req.session.save() time.sleep(0.8) # confirm even after the session was created 1.6 sec ago hasn't # been closed self.assertEqual( req.session_id, self._create_ussd_request(phone_number).session_id ) time.sleep(0.3) # test now the session has been closed self.assertNotEqual( req.session_id, self._create_ussd_request(phone_number).session_id )
def test_date_time_conversion(self): now = datetime.now() now_str = datetime_to_string(now) self.assertEqual(now, string_to_datetime(now_str))
def test_steps_recording(self): ussd_client = self.get_client() # dial in ussd_client.send('') # enter first name ussd_client.send('Francis') # enter second name ussd_client.send('Mwangi') # enter 1 to continue ussd_client.send('1') # press two to go back ussd_client.send('2') # enter 1 to continue ussd_client.send('1') # enter 1 to exit self.assertEqual("This is the last screen", ussd_client.send('1')) now = datetime_to_string(datetime.now()) expected_screen_interaction = [{ "screen_name": "screen_one", "screen_text": "Enter anything\n", "input": "Francis", "start_time": now, "end_time": now, "duration": 0.0 }, { "screen_name": "screen_two", "screen_text": "Enter anything\n", "input": "Mwangi", "start_time": now, "end_time": now, "duration": 0.0 }, { "screen_name": "screen_three", "screen_text": "First input was Francis and " "second input was Mwangi\n1. Continue\n", "input": "1", "start_time": now, "end_time": now, "duration": 0.0 }, { "screen_name": "screen_four", "screen_text": "Press 1 to exit or 2 to go back\n" "1. Exit\n" "2. Back\n", "input": "2", "start_time": now, "end_time": now, "duration": 0.0 }, { "screen_name": "screen_three", "screen_text": "First input was Francis and " "second input was Mwangi\n1. Continue\n", "input": "1", "start_time": now, "end_time": now, "duration": 0.0 }, { "screen_name": "screen_four", "screen_text": "Press 1 to exit or 2 to go back\n" "1. Exit\n" "2. Back\n", "input": "1", "start_time": now, "end_time": now, "duration": 0.0 }, { "screen_name": "screen_five", "screen_text": "This is the last screen", "input": "", "start_time": now }] session = self.ussd_session(ussd_client.session_id) self.assertEqual(session['ussd_interaction'], expected_screen_interaction)
def test_steps_recording(self): ussd_client = self.get_client() # dial in ussd_client.send('') # enter first name ussd_client.send('Francis') # enter second name ussd_client.send('Mwangi') # enter 1 to continue ussd_client.send('1') # press two to go back ussd_client.send('2') # enter 1 to continue ussd_client.send('1') # enter 1 to exit self.assertEqual( "This is the last screen", ussd_client.send('1') ) now = datetime_to_string(datetime.now()) expected_screen_interaction = [ { "screen_name": "screen_one", "screen_text": "Enter anything\n", "input": "Francis", "start_time": now, "end_time": now, "duration": 0.0 }, { "screen_name": "screen_two", "screen_text": "Enter anything\n", "input": "Mwangi", "start_time": now, "end_time": now, "duration": 0.0 }, { "screen_name": "screen_three", "screen_text": "First input was Francis and " "second input was Mwangi\n1. Continue\n", "input": "1", "start_time": now, "end_time": now, "duration": 0.0 }, { "screen_name": "screen_four", "screen_text": "Press 1 to exit or 2 to go back\n" "1. Exit\n" "2. Back\n", "input": "2", "start_time": now, "end_time": now, "duration": 0.0 }, { "screen_name": "screen_three", "screen_text": "First input was Francis and " "second input was Mwangi\n1. Continue\n", "input": "1", "start_time": now, "end_time": now, "duration": 0.0 }, { "screen_name": "screen_four", "screen_text": "Press 1 to exit or 2 to go back\n" "1. Exit\n" "2. Back\n", "input": "1", "start_time": now, "end_time": now, "duration": 0.0 }, { "screen_name": "screen_five", "screen_text": "This is the last screen", "input": "", "start_time": now } ] session = ussd_session(ussd_client.session_id) self.assertEqual( session['ussd_interaction'], expected_screen_interaction )