예제 #1
0
 def derive_initial(self):
     trigger = self.object
     trigger_type = trigger.trigger_type
     if trigger_type == Trigger.TYPE_SCHEDULE:
         repeat_period = trigger.schedule.repeat_period
         omnibox = omnibox_serialize(trigger.org, trigger.groups.all(), trigger.contacts.all())
         return dict(repeat_period=repeat_period, omnibox=omnibox)
예제 #2
0
    def test_update_near_day_boundary(self):
        self.org.timezone = pytz.timezone("US/Eastern")
        self.org.save()
        tz = self.org.timezone

        omnibox = omnibox_serialize(self.org, [], [self.joe], True)

        self.login(self.admin)
        post_data = dict(text="A scheduled message to Joe",
                         omnibox=omnibox,
                         sender=self.channel.pk,
                         schedule=True)
        self.client.post(reverse("msgs.broadcast_send"),
                         post_data,
                         follow=True)

        bcast = Broadcast.objects.get()
        sched = bcast.schedule

        update_url = reverse("schedules.schedule_update", args=[sched.pk])

        # way off into the future, but at 11pm NYT
        start_date = datetime(2050, 1, 3, 23, 0, 0, 0)
        start_date = tz.localize(start_date)
        start_date = pytz.utc.normalize(start_date.astimezone(pytz.utc))

        post_data = dict()
        post_data["repeat_period"] = "D"
        post_data["start"] = "later"
        post_data["start_datetime_value"] = "%d" % time.mktime(
            start_date.timetuple())
        self.client.post(update_url, post_data)
        sched = Schedule.objects.get(pk=sched.pk)

        # 11pm in NY should be 4am UTC the next day
        self.assertEqual("2050-01-04 04:00:00+00:00", str(sched.next_fire))

        start_date = datetime(2050, 1, 3, 23, 45, 0, 0)
        start_date = tz.localize(start_date)
        start_date = pytz.utc.normalize(start_date.astimezone(pytz.utc))

        post_data = dict()
        post_data["repeat_period"] = "D"
        post_data["start"] = "later"
        post_data["start_datetime_value"] = "%d" % time.mktime(
            start_date.timetuple())
        self.client.post(update_url, post_data)
        sched = Schedule.objects.get(pk=sched.pk)

        # next fire should fall at the right hour and minute
        self.assertIn("04:45:00+00:00", str(sched.next_fire))
예제 #3
0
파일: tests.py 프로젝트: resistbot/rapidpro
    def test_update(self):
        self.login(self.admin)

        # create a schedule broadcast
        self.client.post(
            reverse("msgs.broadcast_send"),
            {
                "text": "A scheduled message to Joe",
                "omnibox": omnibox_serialize(self.org, [], [self.joe], True),
                "sender": self.channel.id,
                "schedule": True,
            },
        )

        schedule = Broadcast.objects.get().schedule

        update_url = reverse("schedules.schedule_update", args=[schedule.id])

        # viewer can't access
        self.login(self.user)
        response = self.client.get(update_url)
        self.assertLoginRedirect(response)

        # editor can access
        self.login(self.editor)
        response = self.client.get(update_url)
        self.assertEqual(response.status_code, 200)

        # as can admin user
        self.login(self.admin)
        response = self.client.get(update_url)
        self.assertEqual(response.status_code, 200)

        now = timezone.now()
        now_stamp = time.mktime(now.timetuple())

        tommorrow = now + timedelta(days=1)
        tommorrow_stamp = time.mktime(tommorrow.timetuple())

        # user in other org can't make changes
        self.login(self.admin2)
        response = self.client.post(update_url, {"start": "never", "repeat_period": "D"})
        self.assertLoginRedirect(response)

        # check schedule is unchanged
        schedule.refresh_from_db()
        self.assertEqual("O", schedule.repeat_period)

        self.login(self.admin)

        # update to never start
        response = self.client.post(update_url, {"start": "never", "repeat_period": "O"})
        self.assertEqual(302, response.status_code)

        schedule.refresh_from_db()
        self.assertIsNone(schedule.next_fire)

        self.client.post(update_url, {"start": "stop", "repeat_period": "O"})

        schedule.refresh_from_db()
        self.assertIsNone(schedule.next_fire)

        response = self.client.post(
            update_url, {"start": "now", "repeat_period": "O", "start_datetime_value": "%d" % now_stamp}
        )
        self.assertEqual(302, response.status_code)

        schedule.refresh_from_db()
        self.assertEqual(schedule.repeat_period, "O")
        self.assertFalse(schedule.next_fire)

        response = self.client.post(
            update_url, {"repeat_period": "D", "start": "later", "start_datetime_value": "%d" % tommorrow_stamp}
        )
        self.assertEqual(302, response.status_code)

        schedule.refresh_from_db()
        self.assertEqual(schedule.repeat_period, "D")

        response = self.client.post(
            update_url, {"repeat_period": "D", "start": "later", "start_datetime_value": "%d" % tommorrow_stamp}
        )
        self.assertEqual(302, response.status_code)

        schedule.refresh_from_db()
        self.assertEqual(schedule.repeat_period, "D")

        # can't omit repeat_days_of_week for weekly
        response = self.client.post(
            update_url,
            {
                "repeat_period": "W",
                "start": "later",
                "repeat_days_of_week": "",
                "start_datetime_value": str(now_stamp),
            },
        )

        self.assertFormError(response, "form", "__all__", "Must specify at least one day of the week")

        schedule.refresh_from_db()
        self.assertEqual(schedule.repeat_period, "D")  # unchanged
        self.assertEqual(schedule.repeat_days_of_week, "")

        # can't set repeat_days_of_week to invalid day
        response = self.client.post(
            update_url,
            {
                "repeat_period": "W",
                "start": "later",
                "repeat_days_of_week": "X",
                "start_datetime_value": str(now_stamp),
            },
        )

        self.assertFormError(response, "form", "repeat_days_of_week", "X is not a valid day of the week")

        schedule.refresh_from_db()
        self.assertEqual(schedule.repeat_period, "D")  # unchanged
        self.assertEqual(schedule.repeat_days_of_week, "")

        # can set to valid days
        response = self.client.post(
            update_url,
            {
                "repeat_period": "W",
                "start": "later",
                "repeat_days_of_week": "MF",
                "start_datetime_value": str(now_stamp),
            },
        )

        self.assertEqual(response.status_code, 302)

        schedule.refresh_from_db()
        self.assertEqual(schedule.repeat_period, "W")
        self.assertEqual(schedule.repeat_days_of_week, "MF")
예제 #4
0
파일: tests.py 프로젝트: resistbot/rapidpro
    def test_schedule_ui(self):
        self.login(self.admin)

        joe = self.create_contact("Joe Blow", "123")

        # test missing recipients
        omnibox = omnibox_serialize(self.org, [], [], True)
        post_data = dict(text="message content", omnibox=omnibox, sender=self.channel.pk, schedule=True)
        response = self.client.post(reverse("msgs.broadcast_send"), post_data, follow=True)
        self.assertContains(response, "At least one recipient is required")

        # missing message
        omnibox = omnibox_serialize(self.org, [], [self.joe], True)
        post_data = dict(text="", omnibox=omnibox, sender=self.channel.pk, schedule=True)
        response = self.client.post(reverse("msgs.broadcast_send"), post_data, follow=True)
        self.assertContains(response, "This field is required")

        # finally create our message
        post_data = dict(text="A scheduled message to Joe", omnibox=omnibox, sender=self.channel.pk, schedule=True)

        headers = {"HTTP_X_PJAX": "True"}
        response = self.client.post(reverse("msgs.broadcast_send"), post_data, **headers)
        self.assertIn("/broadcast/schedule_read", response["Temba-Success"])

        # should have a schedule with no next fire
        bcast = Broadcast.objects.get()
        schedule = bcast.schedule

        self.assertIsNone(schedule.next_fire)
        self.assertEqual(Schedule.REPEAT_NEVER, schedule.repeat_period)

        # fetch our formax page
        response = self.client.get(response["Temba-Success"])
        self.assertContains(response, "id-schedule")
        broadcast = response.context["object"]

        # update our message
        post_data = dict(message="An updated scheduled message", omnibox="c-%s" % joe.uuid)
        self.client.post(reverse("msgs.broadcast_update", args=[broadcast.pk]), post_data)
        self.assertEqual(Broadcast.objects.get(id=broadcast.id).text, {"base": "An updated scheduled message"})

        start = datetime(2045, 9, 19, hour=10, minute=15, second=0, microsecond=0)
        start = pytz.utc.normalize(self.org.timezone.localize(start))
        start_stamp = time.mktime(start.timetuple())

        # update the schedule
        post_data = dict(
            repeat_period=Schedule.REPEAT_WEEKLY,
            repeat_days_of_week="W",
            start="later",
            start_datetime_value=start_stamp,
        )
        response = self.client.post(reverse("schedules.schedule_update", args=[broadcast.schedule.pk]), post_data)

        # assert out next fire was updated properly
        schedule.refresh_from_db()
        self.assertEqual(Schedule.REPEAT_WEEKLY, schedule.repeat_period)
        self.assertEqual("W", schedule.repeat_days_of_week)
        self.assertEqual(10, schedule.repeat_hour_of_day)
        self.assertEqual(15, schedule.repeat_minute_of_hour)
        self.assertEqual(start, schedule.next_fire)

        # manually set our fire in the past
        schedule.next_fire = timezone.now() - timedelta(days=1)
        schedule.save(update_fields=["next_fire"])

        self.assertIsNotNone(str(schedule))
예제 #5
0
    def test_trigger_schedule(self, mock_async_start):
        self.login(self.admin)
        flow = self.create_flow()

        chester = self.create_contact("Chester", "+250788987654")
        shinoda = self.create_contact("Shinoda", "+250234213455")
        linkin_park = self.create_group("Linkin Park", [chester, shinoda])
        stromae = self.create_contact("Stromae", "+250788645323")

        now = timezone.now()
        now_stamp = time.mktime(now.timetuple())

        tommorrow = now + timedelta(days=1)
        tommorrow_stamp = time.mktime(tommorrow.timetuple())

        omnibox_selection = omnibox_serialize(flow.org, [linkin_park],
                                              [stromae], True)

        # try to create trigger without a flow or omnibox
        response = self.client.post(
            reverse("triggers.trigger_schedule"),
            {
                "omnibox": omnibox_selection,
                "repeat_period": "D",
                "start": "later",
                "start_datetime_value": str(tommorrow_stamp),
            },
        )

        self.assertEqual(list(response.context["form"].errors.keys()),
                         ["flow"])
        self.assertFalse(Trigger.objects.all())
        self.assertFalse(Schedule.objects.all())

        # survey flows should not be an option
        flow.flow_type = Flow.TYPE_SURVEY
        flow.save(update_fields=("flow_type", ))

        response = self.client.get(reverse("triggers.trigger_schedule"))

        # check no flows listed
        self.assertEqual(
            response.context["form"].fields["flow"].queryset.all().count(), 0)

        # revert flow to messaging flow type
        flow.flow_type = Flow.TYPE_MESSAGE
        flow.save(update_fields=("flow_type", ))

        self.assertEqual(
            response.context["form"].fields["flow"].queryset.all().count(), 1)

        # this time provide a flow but leave out omnibox..
        response = self.client.post(
            reverse("triggers.trigger_schedule"),
            {
                "flow": flow.id,
                "repeat_period": "D",
                "start": "later",
                "start_datetime_value": str(tommorrow_stamp)
            },
        )
        self.assertEqual(list(response.context["form"].errors.keys()),
                         ["omnibox"])
        self.assertFalse(Trigger.objects.all())
        self.assertFalse(Schedule.objects.all())

        # ok, really create it
        self.client.post(
            reverse("triggers.trigger_schedule"),
            {
                "flow": flow.id,
                "omnibox": omnibox_selection,
                "repeat_period": "D",
                "start": "later",
                "start_datetime_value": str(tommorrow_stamp),
            },
        )

        self.assertEqual(Trigger.objects.count(), 1)

        self.client.post(
            reverse("triggers.trigger_schedule"),
            {
                "flow": flow.id,
                "omnibox": omnibox_selection,
                "repeat_period": "D",
                "start": "later",
                "start_datetime_value": str(tommorrow_stamp),
            },
        )

        self.assertEqual(2, Trigger.objects.all().count())

        trigger = Trigger.objects.order_by("id").last()

        self.assertTrue(trigger.schedule)
        self.assertEqual(trigger.schedule.repeat_period, "D")
        self.assertEqual(set(trigger.groups.all()), {linkin_park})
        self.assertEqual(set(trigger.contacts.all()), {stromae})

        update_url = reverse("triggers.trigger_update", args=[trigger.pk])

        # try to update a trigger without a flow
        response = self.client.post(
            update_url,
            {
                "omnibox": omnibox_selection,
                "repeat_period": "O",
                "start": "later",
                "start_datetime_value": str(now_stamp),
            },
        )

        self.assertEqual(list(response.context["form"].errors.keys()),
                         ["flow"])

        # provide flow this time, update contact
        self.client.post(
            update_url,
            {
                "flow":
                flow.id,
                "omnibox":
                omnibox_serialize(flow.org, [linkin_park], [shinoda], True),
                "repeat_period":
                "D",
                "start":
                "later",
                "start_datetime_value":
                str(now_stamp),
            },
        )

        trigger.refresh_from_db()

        self.assertTrue(trigger.schedule)
        self.assertEqual(trigger.schedule.repeat_period, "D")
        self.assertTrue(trigger.schedule.next_fire)
        self.assertEqual(set(trigger.groups.all()), {linkin_park})
        self.assertEqual(set(trigger.contacts.all()), {shinoda})

        # can't submit weekly repeat without specifying the days to repeat on
        response = self.client.post(
            update_url,
            {
                "flow": flow.id,
                "omnibox": omnibox_selection,
                "repeat_period": "W",
                "start": "later",
                "start_datetime_value": str(now_stamp),
            },
        )

        self.assertFormError(response, "form", "__all__",
                             "Must specify at least one day of the week")

        # or submit with invalid days
        response = self.client.post(
            update_url,
            {
                "flow": flow.id,
                "omnibox": omnibox_selection,
                "repeat_period": "W",
                "repeat_days_of_week": "X",
                "start": "later",
                "start_datetime_value": str(now_stamp),
            },
        )

        self.assertFormError(response, "form", "repeat_days_of_week",
                             "X is not a valid day of the week")