Example #1
0
    def testStrictRules(self):
        step = ScriptStep.objects.get(script__slug='test_autoreg', order=2)
        # modify setUp() ScriptStep 2 to be LENIENT
        step.rule = ScriptStep.STRICT_MOVEON
        step.num_tries = 2
        step.retry_offset = 60
        step.giveup_offset = 0
        step.save()

        # dummy progress, the question for step two has been sent out, now we check
        # that any response (even erroneous) advances progress
        connection = Connection.objects.all()[0]
        script = Script.objects.get(slug="test_autoreg")
        step = ScriptStep.objects.get(script__slug='test_autoreg', order=2)
        prog = ScriptProgress.objects.create(connection=connection, script=script, step=step, status='P')
        # create a dummy session
        session = ScriptSession.objects.create(connection=connection, script=script)
        incomingmessage = self.fakeIncoming('Jack cheese is a cheese that I like')
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(response_message, "We didn't understand your response and it's very important to know about your cheese desires.  Please resend.")
        self.assertEquals(Response.objects.count(), 1)

        # refresh progress
        prog = ScriptProgress.objects.get(connection=connection)
        # check that this erroneous poll response DID update the progress,
        # since the rule is now lenient
        r = Response.objects.order_by('-date')[0]
        self.failUnless(r.has_errors)
        self.assertEquals(prog.step.order, 2)
        self.assertEquals(prog.status, 'P')
        self.assertEquals(prog.num_tries, 1)

        incomingmessage = self.fakeIncoming('Well, I also like cheddar')
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(response_message, "We didn't understand your response and it's very important to know about your cheese desires.  Please resend.")
        self.assertEquals(Response.objects.count(), 2)

        # refresh progress
        prog = ScriptProgress.objects.get(connection=connection)
        # check that this erroneous poll response DID update the progress,
        # since the rule is now lenient
        r = Response.objects.order_by('-date')[0]
        self.failUnless(r.has_errors)
        self.assertEquals(prog.step.order, 2)
        self.assertEquals(prog.status, 'P')
        self.assertEquals(prog.num_tries, 2)

        check_progress(self.script)
        # refresh progress
        prog = ScriptProgress.objects.get(connection=connection)
        self.assertEquals(prog.step.order, 2)
        self.assertEquals(prog.status, 'C')
Example #2
0
    def testIncomingProgress(self):
        connection = Connection.objects.all()[0]
        script = Script.objects.get(slug="test_autoreg")
        step = ScriptStep.objects.get(script__slug='test_autoreg', order=1)
        prog = ScriptProgress.objects.create(connection=connection, script=script, step=step, status='P')

        # create a dummy session
        session = ScriptSession.objects.create(connection=connection, script=script)
        incomingmessage = self.fakeIncoming('I like all forms of spam, but typically Nigerian email spam is the best.')
        incoming_progress(incomingmessage)
        self.assertEquals(Response.objects.count(), 1)
        self.assertEquals(ScriptSession.objects.count(), 1)
        self.assertEquals(ScriptSession.objects.all()[0].responses.count(), 1)

        # refresh progress
        prog = ScriptProgress.objects.get(connection=connection)
        self.assertEquals(prog.step.order, 1)
        self.assertEquals(prog.status, 'C')

        # manually move to next step, check_progress would do this
        prog.step = ScriptStep.objects.get(script__slug='test_autoreg', order=2)
        prog.status = 'P'
        prog.save()

        incomingmessage = self.fakeIncoming('Jack cheese is a cheese that I like')
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(response_message, "We didn't understand your response and it's very important to know about your cheese desires.  Please resend.")
        self.assertEquals(Response.objects.count(), 2)

        # refresh progress
        prog = ScriptProgress.objects.get(connection=connection)
        # check that this erroneous poll response didn't update the progress
        r = Response.objects.order_by('-date')[0]
        self.failUnless(r.has_errors)
        self.assertEquals(prog.step.order, 2)
        self.assertEquals(prog.status, 'P')

        incomingmessage = self.fakeIncoming('YES I like jack cheese you silly poll!!!eleventyone')
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(response_message, "It's very good to know that you like cheese!")
        r = Response.objects.order_by('-date')[0]
        self.failIf(r.has_errors)
        self.assertEquals(Response.objects.count(), 3)

        # refresh progress
        prog = ScriptProgress.objects.get(connection=connection)
        # check that this correct poll response updated the progress
        self.assertEquals(prog.step.order, 2)
        self.assertEquals(prog.status, 'C')
    def handle (self, message):
        reg = re.compile('COMPLETE|DAMAGED')
        waybills = filter(None, reg.split(message.db_message.text.upper()))
        if len(waybills) > 0:
            for waybill in waybills:   
#            waybill=waybill_match.group('waybill')
                delivery=Delivery.objects.get(waybill=waybill.strip())
                
                #check if message is from consignee
                if delivery.consignee.default_connection.identity == message.connection.identity:
                    delivery.status = Delivery.DELIVERED
                    delivery.date_delivered = datetime.datetime.now()
                    delivery.save()
                    
                    #if it is in the backlog, delete it
                    if DeliveryBackLog.objects.filter(delivery__waybill=waybill.strip()).exists():
                        DeliveryBackLog.objects.get(delivery=delivery).delete()
                    
            #in case consignee has sent delivery report, send it out to supply admins        
            if delivery.consignee.default_connection.identity == message.connection.identity:
                supply_admins = Contact.objects.filter(groups__name__in=['supply_admin'])
                recipients = list(supply_admins.values_list('user__email',flat=True).distinct())
                sender = '*****@*****.**'
                subject = 'SupplyTracking: Delivery Report'
                message = message.db_message.text
                if message.strip():
                    send_mail(subject, message, sender, recipients, fail_silently=False)  
            
            #process and send out response to message sender
            response = incoming_progress(message)
            if response:
                message.respond(response)
            return True      
        else:
            return False
Example #4
0
    def testLenient(self):
        step = ScriptStep.objects.get(script__slug='test_autoreg', order=2)
        # modify setUp() ScriptStep 2 to be LENIENT
        step.rule = ScriptStep.LENIENT
        step.save()

        # dummy progress, the question for step two has been sent out, now we check
        # that any response (even erroneous) advances progress
        connection = Connection.objects.all()[0]
        script = Script.objects.get(slug="test_autoreg")
        step = ScriptStep.objects.get(script__slug='test_autoreg', order=2)
        prog = ScriptProgress.objects.create(connection=connection,
                                             script=script,
                                             step=step,
                                             status='P')
        # create a dummy session
        session = ScriptSession.objects.create(connection=connection,
                                               script=script)
        incomingmessage = self.fakeIncoming(
            'Jack cheese is a cheese that I like')
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(
            response_message,
            "We didn't understand your response and it's very important to know about your cheese desires.  Please resend."
        )
        self.assertEquals(Response.objects.count(), 1)

        # refresh progress
        prog = ScriptProgress.objects.get(connection=connection)
        # check that this erroneous poll response DID update the progress,
        # since the rule is now lenient
        r = Response.objects.order_by('-date')[0]
        self.failUnless(r.has_errors)
        self.assertEquals(prog.step.order, 2)
        self.assertEquals(prog.status, 'C')
 def testTransporterScript(self):
     #upload excel, this should result into creation of a delivery
    upload_file = open(os.path.join(os.path.join(os.path.realpath(os.path.dirname(__file__)),'fixtures'),'excel.xls'), 'rb')
    file_dict = {'excel_file': SimpleUploadedFile(upload_file.name, upload_file.read())}
    form = UploadForm({},file_dict)
    self.assertTrue(form.is_valid())
    msg = handle_excel_file(form.cleaned_data['excel_file'])
    
    #wait one day and upload another excel
    progress = ScriptProgress.objects.get(connection=Contact.objects.get(name='3ways shipping').default_connection)
    self.elapseTime(progress, 86401)
    upload_file = open(os.path.join(os.path.join(os.path.realpath(os.path.dirname(__file__)),'fixtures'),'excel2.xls'), 'rb')
    file_dict = {'excel_file': SimpleUploadedFile(upload_file.name, upload_file.read())}
    form = UploadForm({},file_dict)
    self.assertTrue(form.is_valid())
    msg = handle_excel_file(form.cleaned_data['excel_file'])
    
    #transporter has different shipments in shipped status
    self.assertEquals(Delivery.objects.filter(transporter=Contact.objects.get(name='3ways shipping'),status='S').count(), 4)
    
    #transporter does not advance to step 0 before the start_offset time has expired
    transporter_script=Script.objects.get(slug='transporter')
    default_connection = Contact.objects.get(name='3ways shipping').default_connection
    transporter_connection = default_connection.pk
    response = check_progress(transporter_connection)
    self.assertEquals(progress.step, None)
    self.assertEquals(response, None)
    
    #elapse 3 days
    self.elapseTime(progress, 259201)
    
    #transporter should advance to step 0 of transporter script for deliveries uploaded 3 or more days ago
    response = check_progress(transporter_connection)
    progress = ScriptProgress.objects.get(connection=transporter_connection, script=transporter_script)
    self.assertEquals(progress.step.order, 0)
    response_msg = Template(response)
    self.assertEquals(response_msg.render(Context(transporter_connection)), 'Has the consignment been delivered?')
    self.assertEquals(Delivery.objects.filter(transporter=Contact.objects.get(name='3ways shipping'), status='S').count(), 4)
    self.assertEquals(DeliveryBackLog.objects.get(delivery__waybill='kp/wb11/00037'), Delivery.objects.get(waybill='kp/wb11/00037'))
    
    #transporter sending delivery message does not affect delivery status
    incomingmessage = self.fakeIncoming('kp/wb11/00034 Delivered')
    response_message = incoming_progress(incomingmessage)
    self.assertEquals(response_message, "Thanks for your response")
    progress = ScriptProgress.objects.get(connection=transporter_connection, script=transporter_script)
    self.assertEquals(Delivery.objects.get(waybill='kp/wb11/00034').status, 'S')
    #new delivery objects are thrown into backlog since there is already an active script progression for admins
    self.assertEquals(DeliveryBackLog.objects.get(delivery__waybill='kp/wb11/00037'), Delivery.objects.get(waybill='kb/wb11/00037'))
Example #6
0
    def handle (self, message):
        try:
            progress = ScriptProgress.objects.filter(connection=message.connection, time__lte=datetime.datetime.now()).order_by('-time')
            if progress.count():
                progress = progress[0]
                script_last_step = ScriptStep.objects.filter(script=progress.script).order_by('-order')[0]
                if progress.step and progress.step.order == script_last_step.order and progress.status == 'C':
                    return False
                else:
                    response = incoming_progress(message)
                    if response:
                        message.respond(gettext_db(response,progress.language))
                    return True
        except ScriptProgress.DoesNotExist:
            pass

        return False
 def testConsigneeScript(self):
    #upload excel, this should result into creation of a delivery
    upload_file = open(os.path.join(os.path.join(os.path.realpath(os.path.dirname(__file__)),'fixtures'),'excel.xls'), 'rb')
    file_dict = {'excel_file': SimpleUploadedFile(upload_file.name, upload_file.read())}
    form = UploadForm({},file_dict)
    self.assertTrue(form.is_valid())
    msg = handle_excel_file(form.cleaned_data['excel_file'])
    
    #wait one day and upload another excel
    self.elapseTime(progress[0], 86401)
    upload_file = open(os.path.join(os.path.join(os.path.realpath(os.path.dirname(__file__)),'fixtures'),'excel2.xls'), 'rb')
    file_dict = {'excel_file': SimpleUploadedFile(upload_file.name, upload_file.read())}
    form = UploadForm({},file_dict)
    self.assertTrue(form.is_valid())
    msg = handle_excel_file(form.cleaned_data['excel_file'])
    
    #consignee has different shipments in shipped status
    self.assertEquals(Delivery.objects.filter(consignee=Contact.objects.get(name='action against hunger', status='S')).count(), 2)
    
    #consignee has not yet advanced into the script (step 0)
    consignee_script=Script.objects.get(slug='consignee')
    consignee_connection = Contact.objects.get(name='action against hunger').default_connection
    progress = ScriptProgress.objects.create(connection=consignee_connection, script=consignee_script)
    response = check_progress(consignee_connection)
    self.assertEquals(progress.step, None)
    self.assertEquals(response, None)
    
    #elapse 3 days
    self.elapseTime(progress, 259201)
    
    #consignee should advance to step 0 of consignee script for deliveries uploaded 3 more days ago
    response = check_progress(consignee_connection)
    progress = ScriptProgress.objects.get(connection=consignee_connection, script=consignee_script)
    self.assertEquals(progress.step.order, 0)
    self.assertEquals(response, 'Has the consignment been delivered?')
    self.assertEquals(Delivery.objects.filter(consignee=Contact.objects.get(name='action against hunger', status='S')).count(), 2)
    self.assertEquals(DeliveryBackLog.objects.get(delivery__waybill='kp/wb11/00037'), Delivery.objects.get(waybill='kp/wb11/00037'))
    
    #consignee sending in a delivery message should complete the script for transporter and consignee and mark orders as delivered
    incomingmessage = self.fakeIncoming('kp/wb11/00034 COMPLETE kb/wb11/00037 COMPLETE')
    response_message = incoming_progress(incomingmessage)
    self.assertEquals(response_message, "Thanks for your response")
    progress = ScriptProgress.objects.get(connection=consignee_connection, script=consignee_script)
    self.assertEquals(Delivery.objects.filter(consignee=Contact.objects.get(name='action against hunger', status='D')).count(), 2)
    self.assertEquals(DeliveryBackLog.objects.filter(delivery__consignee=Contact.objects.get(name='action against hunger')), None)
Example #8
0
    def handle(self, message):
        try:
            progress = ScriptProgress.objects.filter(
                connection=message.connection,
                time__lte=datetime.datetime.now()).order_by('-time')
            if progress.count():
                progress = progress[0]
                script_last_step = ScriptStep.objects.filter(
                    script=progress.script).order_by('-order')[0]
                if progress.step and progress.step.order == script_last_step.order and progress.status == 'C':
                    return False
                else:
                    response = incoming_progress(message)
                    if response:
                        message.respond(gettext_db(response,
                                                   progress.language))
                    return True
        except ScriptProgress.DoesNotExist:
            pass

        return False
Example #9
0
    def handle (self, message):
        if handle_dongle_sms(message):
            return True

        if message.text.strip().lower() in [i.lower() for i in getattr(settings, 'OPT_OUT_WORDS', ['quit'])]:

            if Blacklist.objects.filter(connection=message.connection).exists():
                message.respond('You cannot send Quit to 6200 (EduTrac) more than once.')
                return True
            else:
                if ScriptProgress.objects.filter(connection=message.connection, script__slug='edtrac_autoreg').exists():
                    # user is attempting to quit before completing registration
                    message.respond('Your registration is not complete. You cannot quit at this point.')
                    return True

                Blacklist.objects.create(connection=message.connection)
                ScriptProgress.objects.filter(connection=message.connection).delete() # delete all script progress since the user has quit
                ScriptSession.objects.filter(connection=message.connection, end_time=None).delete() # the non closed out sessions need to be expunged as well
                if (message.connection.contact):
                    message.connection.contact.active = False
                    message.connection.contact.save()
                message.respond(getattr(settings, 'OPT_OUT_CONFIRMATION', 'Thank you for your contribution to EduTrac. To rejoin the system, send join to 6200'))
                return True

        elif message.text.strip().lower() in [i.lower() for i in getattr(settings, 'OPT_IN_WORDS', ['join'])]:

            if not message.connection.contact:
                if ScriptProgress.objects.filter(script__slug='edtrac_autoreg', connection=message.connection).count() == 0:
                    ScriptProgress.objects.create(script=Script.objects.get(slug="edtrac_autoreg"),\
                        connection=message.connection)
                else:
                    message.respond("Your registration is not complete yet, you do not need to 'Join' again.")
            elif Blacklist.objects.filter(connection=message.connection).exists():
                Blacklist.objects.filter(connection=message.connection).delete()
                if not ScriptProgress.objects.filter(script__slug='edtrac_autoreg', connection=message.connection).count():
                    ScriptProgress.objects.create(script=Script.objects.get(slug="edtrac_autoreg"),\
                        connection=message.connection)
            else:
                message.respond("You are already in the system and do not need to 'Join' again.")
            return True

        elif Blacklist.objects.filter(connection=message.connection).count():
            return True
            # when all else fails, quit!

        else:
            try:
                progress = ScriptProgress.objects.filter(connection=message.connection, time__lte=datetime.datetime.now()).order_by('-time')
                response_message_string = {"n":"The answer you have provided is not in the correct format. Use figures like 3 to answer the question",
                                 "t":"The answer you have provided is not in the correct format. Please follow instructions that were given to you"}
                if progress.count():
                    progress = progress[0]
                    script_last_step = ScriptStep.objects.filter(script=progress.script).order_by('-order')[0]
                    if progress.step and progress.step.order == script_last_step.order and progress.status == 'C':
                        return False
                    else:
                        response = incoming_progress(message)
                        if not progress.script.slug == 'edtrac_autoreg':
                            r = Response.objects.filter(contact__connection=message.connection,date__lte=datetime.datetime.now(),message__text=message.text).latest('date')
                            if r is not None:
                                if r.has_errors:
                                    progress.status = ScriptProgress.PENDING
                                    progress.save()
                                    Message.mass_text(response_message_string[r.poll.type], [message.connection])
                                    Message.mass_text(r.poll.question , [message.connection])
                        if response:
                            message.respond(gettext_db(response,progress.language))
                        return True
            except ScriptProgress.DoesNotExist:
                logger.debug("\nScript Progress object not found for message %s with connection %s" % (message,message.connection))
        return False
Example #10
0
    def handle (self, message):
        if handle_dongle_sms(message):
            return True

        if message.text.strip().lower() in [i.lower() for i in getattr(settings, 'OPT_OUT_WORDS', ['quit'])]:

            if Blacklist.objects.filter(connection=message.connection).exists():
                message.respond('You cannot send Quit to 6200 (EduTrac) more than once.')
                return True
            else:
                if ScriptProgress.objects.filter(connection=message.connection, script__slug='edtrac_autoreg').exists():
                    # user is attempting to quit before completing registration
                    message.respond('Your registration is not complete, you can not quit at this point')
                    return True

                Blacklist.objects.create(connection=message.connection)
                ScriptProgress.objects.filter(connection=message.connection).delete() # delete all script progress since the user has quit
                ScriptSession.objects.filter(connection=message.connection, end_time=None).delete() # the non closed out sessions need to be expunged as well
                if (message.connection.contact):
                    message.connection.contact.active = False
                    message.connection.contact.save()
                message.respond(getattr(settings, 'OPT_OUT_CONFIRMATION', 'Thank you for your contribution to EduTrac. To rejoin the system, send join to 6200'))
                return True

        elif message.text.strip().lower() in [i.lower() for i in getattr(settings, 'OPT_IN_WORDS', ['join'])]:

            if not message.connection.contact:
                if ScriptProgress.objects.filter(script__slug='edtrac_autoreg', connection=message.connection).count() == 0:
                    ScriptProgress.objects.create(script=Script.objects.get(slug="edtrac_autoreg"),\
                        connection=message.connection)
                else:
                    message.respond("Your registration is not complete yet, you do not need to 'Join' again.")
            elif Blacklist.objects.filter(connection=message.connection).exists():
                Blacklist.objects.filter(connection=message.connection).delete()
                if not ScriptProgress.objects.filter(script__slug='edtrac_autoreg', connection=message.connection).count():
                    ScriptProgress.objects.create(script=Script.objects.get(slug="edtrac_autoreg"),\
                        connection=message.connection)
            else:
                message.respond("You are already in the system and do not need to 'Join' again.")
            return True

        elif Blacklist.objects.filter(connection=message.connection).count():
            return True
            # when all else fails, quit!

        else:
            try:
                progress = ScriptProgress.objects.filter(connection=message.connection, time__lte=datetime.datetime.now()).order_by('-time')
                response_message_string = {"n":"The answer you have provided is not in the correct format. Use figures like 3 to answer the question",
                                 "t":"The answer you have provided is not in the correct format. Please follow instructions that were given to you"}
                if progress.count():
                    progress = progress[0]
                    script_last_step = ScriptStep.objects.filter(script=progress.script).order_by('-order')[0]
                    if progress.step and progress.step.order == script_last_step.order and progress.status == 'C':
                        return False
                    else:
                        response = incoming_progress(message)
                        if not progress.script.slug == 'edtrac_autoreg':
                            r = Response.objects.filter(contact__connection=message.connection,date__lte=datetime.datetime.now(),message__text=message.text).latest('date')
                            if r is not None:
                                if r.has_errors:
                                    progress.status = ScriptProgress.PENDING
                                    progress.save()
                                    Message.mass_text(response_message_string[r.poll.type], [message.connection])
                                    Message.mass_text(r.poll.question , [message.connection])
                        if response:
                            message.respond(gettext_db(response,progress.language))
                        return True
            except ScriptProgress.DoesNotExist:
                logger.debug("\nScript Progress object not found for message %s with connection %s" % (message,message.connection))
        return False
Example #11
0
    def testFullScriptFlow(self):
        script = Script.objects.get(slug="test_autoreg")
        connection = Connection.objects.all()[0]
        progress = ScriptProgress.objects.create(connection=connection, script=script)

        # test that an incoming message from a user freshly added to the script
        # (i.e., no call to check_progress yet) doesn't fail
        incomingmessage = self.fakeIncoming('Im in the script, but nothings happened yet.  What next?')
        response_message = incoming_progress(incomingmessage)
        # no response message
        self.assertEquals(response_message, None)
        # refresh progress, no updates to progress should be made
        # no ScriptSession should be created, that's up to check_progress
        progress = self.assertProgress(connection, None, '', 0, 0)

        # modify step 1, check_progress should wait a full minute before sending out
        # the first message
        step0 = script.steps.get(order=0)
        step0.start_offset = 60
        step0.save()

        res_count = Message.objects.filter(direction='O', connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        # we're still waiting to send the first message, for a full minute
        self.assertEquals(response, None)
        self.elapseTime(progress, 60)
        res_count = Message.objects.filter(direction='O', connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        # we're ready for the first message to go out
        self.assertEquals(response, step0.message)
        # refresh progress
        # we should now be advanced to step 0, in 'P'ending status
        # because it's a WAIT_MOVEON step, so we have to wait for one
        # hour before advancing to the next step
        # there should be a scriptsession at this point
        # but there shouldn't be any responses
        progress = self.assertProgress(connection, 0, 'P', 1, 0)

        # test that an incoming message from a user in this portion
        # of the script doesn't affect the progress
        incomingmessage = self.fakeIncoming('Im in the script, but Im waiting to be asked a question.  Why do I have to wait for an hour?')
        response_message = incoming_progress(incomingmessage)
        # no response message
        self.assertEquals(response_message, None)
        # refresh progress
        # no updates to progress
        # there should still be a scriptsession, but only one
        # and there still shouldn't be any responses
        progress = self.assertProgress(connection, 0, 'P', 1, 0)

        # now let's wait a full hour
        self.elapseTime(progress, 3600)
        step1 = script.steps.get(order=1)
        res_count = Message.objects.filter(direction='O', connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        # the first poll question should go out now
        self.assertEquals(response, step1.poll.question)
        # refresh progress
        # check that the step is now step 1, with status 'P'
        # there should still be a scriptsession, but only one
        # and there still shouldn't be any responses
        progress = self.assertProgress(connection, 1, 'P', 1, 0)

        # check that an additional call to check_progress doesn't re-send the
        # question
        res_count = Message.objects.filter(direction='O', connection=connection).count()

        check_progress(self.script)

        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        # the first poll question should go out now
        self.assertEquals(response, None)
        # check that the step is still step 1, with status 'P'
        # there should still be a scriptsession, but only one
        # and there still shouldn't be any responses
        progress = self.assertProgress(connection, 1, 'P', 1, 0)

        # test the moveon scenario, wait a full day with no response
        self.elapseTime(progress, 86400)
        # make sure that incoming_progress respects the giveup time of
        # the previous step and drops any messages (otherwise it's a
        # potential race contidion
        incomingmessage = self.fakeIncoming('I like spam, Im just a little late to mention anything about it')
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(response, None)
        progress = self.assertProgress(connection, 1, 'P', 1, 0)
        # check that this call to check_progress sends out the
        # next question
        res_count = Message.objects.filter(direction='O', connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        step2 = script.steps.get(order=2)
        # the first poll question should go out now
        self.assertEquals(response, step2.poll.question)
        # check that the step is now step 2, with status 'P'
        # there should still be a scriptsession, but only one
        # and there still shouldn't be any responses
        progress = self.assertProgress(connection, 2, 'P', 1, 0)

        # test the scenario where a response is received
        progress.step = step1
        progress.status = 'P'
        progress.save()
        session = ScriptSession.objects.all()[0]
        session.start_time = datetime.datetime.now()
        session.end_time = None
        for r in session.responses.all():
            r.delete()
        for r in Response.objects.all():
            r.delete()
        session.save()

        # test that an incoming message from a user in this portion
        # of the script affects the progress
        step1response = 'My favorite form of spam is an overabundance of test cases ;-)'
        incomingmessage = self.fakeIncoming(step1response)
        response_message = incoming_progress(incomingmessage)
        self.failUnless(response_message == None or response_message == '')
        # we should move the status of step 1 to complete, and there should
        # be one response in the ScriptSession
        progress = self.assertProgress(connection, 1, 'C', 1, 1)
        # test that the response was processed correctly
        self.assertEquals(Response.objects.all()[0].pk, ScriptSession.objects.all()[0].responses.all()[0].response.pk)
        self.assertEquals(Response.objects.all()[0].eav.poll_text_value, step1response)

        # check that this call to check_progress sends out the
        # next question
        res_count = Message.objects.filter(direction='O', connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        # the first poll question should go out now
        self.assertEquals(response, step2.poll.question)
        # check that the step is now step 2, with status 'P'
        # there should still be a scriptsession, but only one
        # and there still should be one response
        progress = self.assertProgress(connection, 2, 'P', 1, 1)

        # no movement until we get a response this time
        res_count = Message.objects.filter(direction='O', connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        self.assertEquals(response, None)
        progress = self.assertProgress(connection, 2, 'P', 1, 1)

        step2errorResponse = 'I like cheese'
        incomingmessage = self.fakeIncoming(step2errorResponse)
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(response_message, step2.poll.categories.get(name='unknown').response)
        # we should be in the same step, with one additional response
        progress = self.assertProgress(connection, 2, 'P', 1, 2)

        res_count = Message.objects.filter(direction='O', connection=connection).count()
        # no movement until we get a response this time
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        self.assertEquals(response, None)
        progress = self.assertProgress(connection, 2, 'P', 1, 2)

        step2yesResponse = 'YES I like cheese'
        incomingmessage = self.fakeIncoming(step2yesResponse)
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(response_message, step2.poll.categories.get(name='yes').response)
        # we should be in the same step, with one additional response and 'C'omplete status
        progress = self.assertProgress(connection, 2, 'C', 1, 3)

        # no movement until for a full hour
        res_count = Message.objects.filter(direction='O', connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        self.assertEquals(response, None)
        progress = self.assertProgress(connection, 2, 'C', 1, 3)

        # incoming messages shouldn't do anything here
        # (in fact, the shouldn't be added even as responses to the poll, since
        # the status of this step is complete)
        incomingmessage = self.fakeIncoming('still just waiting around for another message')
        response_message = incoming_progress(incomingmessage)
        self.failUnless(response_message == None or response_message == '')
        progress = self.assertProgress(connection, 2, 'C', 1, 3)

        # wait an hour
        self.elapseTime(progress, 3601)
        step3 = script.steps.get(order=3)
        res_count = Message.objects.filter(direction='O', connection=connection).count()
        # this should complete the script
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        self.assertEquals(response, step3.message)
        progress = self.assertProgress(connection, 3, 'P', 1, 3)

        # incoming messages shouldn't do anything here
        # (in fact, the shouldn't be added even as responses to the poll, since
        # the status of this step is complete)
        incomingmessage = self.fakeIncoming('im done with the script, just sending random stuff')
        response_message = incoming_progress(incomingmessage)
        self.failUnless(response_message == None or response_message == '')
        progress = self.assertProgress(connection, 3, 'P', 1, 3)

        # wait a few more seconds, then check that the script is closed out
        self.elapseTime(progress, 10)
        res_count = Message.objects.filter(direction='O', connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        self.assertEquals(response, None)
        self.assertEquals(ScriptProgress.objects.count(), 0)
        self.assertEquals(ScriptSession.objects.all()[0].responses.count(), 3)
        self.failIf(ScriptSession.objects.all()[0].end_time is None)
Example #12
0
    def testFullScriptFlow(self):
        script = Script.objects.get(slug="test_autoreg")
        connection = Connection.objects.all()[0]
        progress = ScriptProgress.objects.create(connection=connection,
                                                 script=script)

        # test that an incoming message from a user freshly added to the script
        # (i.e., no call to check_progress yet) doesn't fail
        incomingmessage = self.fakeIncoming(
            'Im in the script, but nothings happened yet.  What next?')
        response_message = incoming_progress(incomingmessage)
        # no response message
        self.assertEquals(response_message, None)
        # refresh progress, no updates to progress should be made
        # no ScriptSession should be created, that's up to check_progress
        progress = self.assertProgress(connection, None, '', 0, 0)

        # modify step 1, check_progress should wait a full minute before sending out
        # the first message
        step0 = script.steps.get(order=0)
        step0.start_offset = 60
        step0.save()

        res_count = Message.objects.filter(direction='O',
                                           connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        # we're still waiting to send the first message, for a full minute
        self.assertEquals(response, None)
        self.elapseTime(progress, 60)
        res_count = Message.objects.filter(direction='O',
                                           connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        # we're ready for the first message to go out
        self.assertEquals(response, step0.message)
        # refresh progress
        # we should now be advanced to step 0, in 'P'ending status
        # because it's a WAIT_MOVEON step, so we have to wait for one
        # hour before advancing to the next step
        # there should be a scriptsession at this point
        # but there shouldn't be any responses
        progress = self.assertProgress(connection, 0, 'P', 1, 0)

        # test that an incoming message from a user in this portion
        # of the script doesn't affect the progress
        incomingmessage = self.fakeIncoming(
            'Im in the script, but Im waiting to be asked a question.  Why do I have to wait for an hour?'
        )
        response_message = incoming_progress(incomingmessage)
        # no response message
        self.assertEquals(response_message, None)
        # refresh progress
        # no updates to progress
        # there should still be a scriptsession, but only one
        # and there still shouldn't be any responses
        progress = self.assertProgress(connection, 0, 'P', 1, 0)

        # now let's wait a full hour
        self.elapseTime(progress, 3600)
        step1 = script.steps.get(order=1)
        res_count = Message.objects.filter(direction='O',
                                           connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        # the first poll question should go out now
        self.assertEquals(response, step1.poll.question)
        # refresh progress
        # check that the step is now step 1, with status 'P'
        # there should still be a scriptsession, but only one
        # and there still shouldn't be any responses
        progress = self.assertProgress(connection, 1, 'P', 1, 0)

        # check that an additional call to check_progress doesn't re-send the
        # question
        res_count = Message.objects.filter(direction='O',
                                           connection=connection).count()

        check_progress(self.script)

        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        # the first poll question should go out now
        self.assertEquals(response, None)
        # check that the step is still step 1, with status 'P'
        # there should still be a scriptsession, but only one
        # and there still shouldn't be any responses
        progress = self.assertProgress(connection, 1, 'P', 1, 0)

        # test the moveon scenario, wait a full day with no response
        self.elapseTime(progress, 86400)
        # make sure that incoming_progress respects the giveup time of
        # the previous step and drops any messages (otherwise it's a
        # potential race contidion
        incomingmessage = self.fakeIncoming(
            'I like spam, Im just a little late to mention anything about it')
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(response, None)
        progress = self.assertProgress(connection, 1, 'P', 1, 0)
        # check that this call to check_progress sends out the
        # next question
        res_count = Message.objects.filter(direction='O',
                                           connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        step2 = script.steps.get(order=2)
        # the first poll question should go out now
        self.assertEquals(response, step2.poll.question)
        # check that the step is now step 2, with status 'P'
        # there should still be a scriptsession, but only one
        # and there still shouldn't be any responses
        progress = self.assertProgress(connection, 2, 'P', 1, 0)

        # test the scenario where a response is received
        progress.step = step1
        progress.status = 'P'
        progress.save()
        session = ScriptSession.objects.all()[0]
        session.start_time = datetime.datetime.now()
        session.end_time = None
        for r in session.responses.all():
            r.delete()
        for r in Response.objects.all():
            r.delete()
        session.save()

        # test that an incoming message from a user in this portion
        # of the script affects the progress
        step1response = 'My favorite form of spam is an overabundance of test cases ;-)'
        incomingmessage = self.fakeIncoming(step1response)
        response_message = incoming_progress(incomingmessage)
        self.failUnless(response_message == None or response_message == '')
        # we should move the status of step 1 to complete, and there should
        # be one response in the ScriptSession
        progress = self.assertProgress(connection, 1, 'C', 1, 1)
        # test that the response was processed correctly
        self.assertEquals(
            Response.objects.all()[0].pk,
            ScriptSession.objects.all()[0].responses.all()[0].response.pk)
        self.assertEquals(Response.objects.all()[0].eav.poll_text_value,
                          step1response)

        # check that this call to check_progress sends out the
        # next question
        res_count = Message.objects.filter(direction='O',
                                           connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        # the first poll question should go out now
        self.assertEquals(response, step2.poll.question)
        # check that the step is now step 2, with status 'P'
        # there should still be a scriptsession, but only one
        # and there still should be one response
        progress = self.assertProgress(connection, 2, 'P', 1, 1)

        # no movement until we get a response this time
        res_count = Message.objects.filter(direction='O',
                                           connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        self.assertEquals(response, None)
        progress = self.assertProgress(connection, 2, 'P', 1, 1)

        step2errorResponse = 'I like cheese'
        incomingmessage = self.fakeIncoming(step2errorResponse)
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(response_message,
                          step2.poll.categories.get(name='unknown').response)
        # we should be in the same step, with one additional response
        progress = self.assertProgress(connection, 2, 'P', 1, 2)

        res_count = Message.objects.filter(direction='O',
                                           connection=connection).count()
        # no movement until we get a response this time
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        self.assertEquals(response, None)
        progress = self.assertProgress(connection, 2, 'P', 1, 2)

        step2yesResponse = 'YES I like cheese'
        incomingmessage = self.fakeIncoming(step2yesResponse)
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(response_message,
                          step2.poll.categories.get(name='yes').response)
        # we should be in the same step, with one additional response and 'C'omplete status
        progress = self.assertProgress(connection, 2, 'C', 1, 3)

        # no movement until for a full hour
        res_count = Message.objects.filter(direction='O',
                                           connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        self.assertEquals(response, None)
        progress = self.assertProgress(connection, 2, 'C', 1, 3)

        # incoming messages shouldn't do anything here
        # (in fact, the shouldn't be added even as responses to the poll, since
        # the status of this step is complete)
        incomingmessage = self.fakeIncoming(
            'still just waiting around for another message')
        response_message = incoming_progress(incomingmessage)
        self.failUnless(response_message == None or response_message == '')
        progress = self.assertProgress(connection, 2, 'C', 1, 3)

        # wait an hour
        self.elapseTime(progress, 3601)
        step3 = script.steps.get(order=3)
        res_count = Message.objects.filter(direction='O',
                                           connection=connection).count()
        # this should complete the script
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        self.assertEquals(response, step3.message)
        progress = self.assertProgress(connection, 3, 'P', 1, 3)

        # incoming messages shouldn't do anything here
        # (in fact, the shouldn't be added even as responses to the poll, since
        # the status of this step is complete)
        incomingmessage = self.fakeIncoming(
            'im done with the script, just sending random stuff')
        response_message = incoming_progress(incomingmessage)
        self.failUnless(response_message == None or response_message == '')
        progress = self.assertProgress(connection, 3, 'P', 1, 3)

        # wait a few more seconds, then check that the script is closed out
        self.elapseTime(progress, 10)
        res_count = Message.objects.filter(direction='O',
                                           connection=connection).count()
        check_progress(self.script)
        response = Message.objects.filter(direction='O', connection=connection)
        if response.exists() and not response.count() == res_count:
            response = response.latest('date').text
        else:
            response = None
        self.assertEquals(response, None)
        self.assertEquals(ScriptProgress.objects.count(), 0)
        self.assertEquals(ScriptSession.objects.all()[0].responses.count(), 3)
        self.failIf(ScriptSession.objects.all()[0].end_time is None)
Example #13
0
    def testIncomingProgress(self):
        connection = Connection.objects.all()[0]
        script = Script.objects.get(slug="test_autoreg")
        step = ScriptStep.objects.get(script__slug='test_autoreg', order=1)
        prog = ScriptProgress.objects.create(connection=connection,
                                             script=script,
                                             step=step,
                                             status='P')

        # create a dummy session
        session = ScriptSession.objects.create(connection=connection,
                                               script=script)
        incomingmessage = self.fakeIncoming(
            'I like all forms of spam, but typically Nigerian email spam is the best.'
        )
        incoming_progress(incomingmessage)
        self.assertEquals(Response.objects.count(), 1)
        self.assertEquals(ScriptSession.objects.count(), 1)
        self.assertEquals(ScriptSession.objects.all()[0].responses.count(), 1)

        # refresh progress
        prog = ScriptProgress.objects.get(connection=connection)
        self.assertEquals(prog.step.order, 1)
        self.assertEquals(prog.status, 'C')

        # manually move to next step, check_progress would do this
        prog.step = ScriptStep.objects.get(script__slug='test_autoreg',
                                           order=2)
        prog.status = 'P'
        prog.save()

        incomingmessage = self.fakeIncoming(
            'Jack cheese is a cheese that I like')
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(
            response_message,
            "We didn't understand your response and it's very important to know about your cheese desires.  Please resend."
        )
        self.assertEquals(Response.objects.count(), 2)

        # refresh progress
        prog = ScriptProgress.objects.get(connection=connection)
        # check that this erroneous poll response didn't update the progress
        r = Response.objects.order_by('-date')[0]
        self.failUnless(r.has_errors)
        self.assertEquals(prog.step.order, 2)
        self.assertEquals(prog.status, 'P')

        incomingmessage = self.fakeIncoming(
            'YES I like jack cheese you silly poll!!!eleventyone')
        response_message = incoming_progress(incomingmessage)
        self.assertEquals(response_message,
                          "It's very good to know that you like cheese!")
        r = Response.objects.order_by('-date')[0]
        self.failIf(r.has_errors)
        self.assertEquals(Response.objects.count(), 3)

        # refresh progress
        prog = ScriptProgress.objects.get(connection=connection)
        # check that this correct poll response updated the progress
        self.assertEquals(prog.step.order, 2)
        self.assertEquals(prog.status, 'C')