示例#1
0
  def test_auto_generate_cycle(self, mock_mail):

    person_1_email = Person.query.get(self.person_1.id).email
    with freeze_time("2015-04-01"):
      _, wf = self.wf_generator.generate_workflow(self.monthly_workflow_1)
      self.wf_generator.activate_workflow(wf)
      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(person_1_email, notif_data)

    with freeze_time("2015-04-02"):
      self.api.client.get("nightly_cron_endpoint")
      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(person_1_email, notif_data)
      start_recurring_cycles()
      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(person_1_email, notif_data)

    # cycle starts on monday - 6th, and not on 5th
    with freeze_time("2015-04-03"):
      start_recurring_cycles()
      _, notif_data = common.get_daily_notifications()
      self.assertIn(person_1_email, notif_data)
      self.assertIn("cycle_started", notif_data[person_1_email])

    with freeze_time("2015-04-15"):  # one day befor due date
      _, notif_data = common.get_daily_notifications()
      self.assertIn(person_1_email, notif_data)

    with freeze_time("2015-04-25"):  # due date
      _, notif_data = common.get_daily_notifications()
      self.assertIn(person_1_email, notif_data)
 def test_cycle_task_group_object_task_update(self):
     """Test cycle task group object task update via import"""
     with freeze_time("2016-10-02"):
         # Generate Workflow, Task Groups and Cycle Task Group Object Tasks
         # objects
         _, workflow = self.wf_generator.generate_workflow(
             self.test_workflow)
         self.wf_generator.activate_workflow(workflow)
         start_recurring_cycles()
         # First test: update 4 tasks with correct CSV import
         self._cmp_tasks(self.exp_tasks_before_update)
         filename = "cycle_task_group_object_task_active_update.csv"
         response = self.import_file(filename)
         expected_errors = {
             "Cycle Task Group Object Task": {
                 "block_warnings": {
                     errors.NON_IMPORTABLE_COLUMN_WARNING.format(
                         line=2,
                         column_name='state',
                     ),
                 }
             }
         }
         self._check_csv_response(response, expected_errors)
         self._cmp_tasks(self.exp_tasks_after_update)
  def test_recurring_without_tgts_skip(self, has_tg):
    """Test that Active Workflow without TGTs is skipped on cron job"""
    with freeze_time(dtm.date(2017, 9, 25)):
      with factories.single_commit():
        workflow = wf_factories.WorkflowFactory(repeat_every=1,
                                                unit=Workflow.MONTH_UNIT)
        workflow_id = workflow.id
        group = wf_factories.TaskGroupFactory(workflow=workflow)
        wf_factories.TaskGroupTaskFactory(
            task_group=group,
            start_date=dtm.date(2017, 9, 26),
            end_date=dtm.date(2017, 9, 26) + dtm.timedelta(days=4))
      self.generator.activate_workflow(workflow)
      active_wf = db.session.query(Workflow).filter(
          Workflow.id == workflow_id).one()
      self.assertEqual(active_wf.next_cycle_start_date, dtm.date(2017, 9, 26))
      self.assertEqual(active_wf.recurrences, True)
      self.assertEqual(len(active_wf.cycles), 0)
      TaskGroupTask.query.delete()
      if not has_tg:
        TaskGroup.query.delete()
      db.session.commit()

    with freeze_time(dtm.date(2017, 10, 25)):
      start_recurring_cycles()
      active_wf = db.session.query(Workflow).filter(
          Workflow.id == workflow_id).one()
      self.assertEqual(active_wf.next_cycle_start_date, dtm.date(2017, 9, 26))
      self.assertEqual(active_wf.recurrences, True)
      self.assertEqual(len(active_wf.cycles), 0)
    def test_recurring_without_tgts_skip(self, has_tg):
        """Test that Active Workflow without TGTs is skipped on cron job"""
        with freeze_time(dtm.date(2017, 9, 25)):
            with factories.single_commit():
                workflow = wf_factories.WorkflowFactory(
                    repeat_every=1, unit=Workflow.MONTH_UNIT)
                workflow_id = workflow.id
                group = wf_factories.TaskGroupFactory(workflow=workflow)
                wf_factories.TaskGroupTaskFactory(
                    task_group=group,
                    start_date=dtm.date(2017, 9, 26),
                    end_date=dtm.date(2017, 9, 26) + dtm.timedelta(days=4))
            self.generator.activate_workflow(workflow)
            active_wf = db.session.query(Workflow).filter(
                Workflow.id == workflow_id).one()
            self.assertEqual(active_wf.next_cycle_start_date,
                             dtm.date(2017, 9, 26))
            self.assertEqual(active_wf.recurrences, True)
            self.assertEqual(len(active_wf.cycles), 0)
            TaskGroupTask.query.delete()
            if not has_tg:
                TaskGroup.query.delete()
            db.session.commit()

        with freeze_time(dtm.date(2017, 10, 25)):
            start_recurring_cycles()
            active_wf = db.session.query(Workflow).filter(
                Workflow.id == workflow_id).one()
            self.assertEqual(active_wf.next_cycle_start_date,
                             dtm.date(2017, 9, 26))
            self.assertEqual(active_wf.recurrences, True)
            self.assertEqual(len(active_wf.cycles), 0)
    def test_auto_generate_cycle(self, mock_mail):

        person_1_email = Person.query.get(self.person_1.id).email
        with freeze_time("2015-04-01"):
            _, wf = self.wf_generator.generate_workflow(
                self.monthly_workflow_1)
            self.wf_generator.activate_workflow(wf)
            _, notif_data = common.get_daily_notifications()
            self.assertNotIn(person_1_email, notif_data)

        with freeze_time("2015-04-02"):
            self.api.client.get("nightly_cron_endpoint")
            _, notif_data = common.get_daily_notifications()
            self.assertNotIn(person_1_email, notif_data)
            start_recurring_cycles()
            _, notif_data = common.get_daily_notifications()
            self.assertNotIn(person_1_email, notif_data)

        # cycle starts on monday - 6th, and not on 5th
        with freeze_time("2015-04-03"):
            start_recurring_cycles()
            _, notif_data = common.get_daily_notifications()
            self.assertIn(person_1_email, notif_data)
            self.assertIn("cycle_started", notif_data[person_1_email])

        with freeze_time("2015-04-15"):  # one day befor due date
            _, notif_data = common.get_daily_notifications()
            self.assertIn(person_1_email, notif_data)

        with freeze_time("2015-04-25"):  # due date
            _, notif_data = common.get_daily_notifications()
            self.assertIn(person_1_email, notif_data)
  def test_annually_workflow(self):
    """Basic annual workflow test.

    """
    annually_wf = {
        "title": "annually thingy",
        "description": "start this many a time",
        "frequency": "annually",
        "task_groups": [{
            "title": "task group",
            "task_group_tasks": [
                {
                    'title': 'annual task 1',
                    "relative_start_day": 10,  # 6/10/2015  Wed
                    "relative_start_month": 6,
                    "relative_end_day": 25,  # 6/25/2015 Thu
                    "relative_end_month": 6,
                },
                {
                    'title': 'annual task 2',
                    "relative_start_day": 15,  # 6/15/2015 Mon
                    "relative_start_month": 6,
                    "relative_end_day": 9,  # 8/9/2015 Sun
                    "relative_end_month": 8,
                }],
            "task_group_objects": self.random_objects
        },
        ]
    }
    with freezegun.freeze_time("2015-6-8 13:00:00"):  # Mon, 6/8/2015
      _, wf = self.generator.generate_workflow(annually_wf)
      _, awf = self.generator.activate_workflow(wf)

      active_wf = db.session.query(models.Workflow).filter(
          models.Workflow.id == wf.id).one()
      self.assertEqual(active_wf.status, "Active")
      self.assertEqual(active_wf.next_cycle_start_date,
                       datetime.date(2015, 6, 10))

    with freezegun.freeze_time("2015-6-10 13:00:00"):  # Mon, 6/8/2015
      start_recurring_cycles()

      cycle = db.session.query(models.Cycle).filter(
          models.Cycle.workflow_id == wf.id).one()

      self.assertEqual(cycle.start_date, datetime.date(2015, 6, 10))
      # Because end date is on Sunday, relative start day will have to be
      # adjusted
      self.assertEqual(cycle.end_date, datetime.date(2015, 8, 7))

      _, cycle = self.generator.generate_cycle(wf)  # 2016
      _, cycle = self.generator.generate_cycle(wf)  # 2017
      _, cycle = self.generator.generate_cycle(wf)  # 2018

      active_wf = db.session.query(models.Workflow).filter(
          models.Workflow.id == wf.id).one()
      self.assertEqual(active_wf.next_cycle_start_date,
                       datetime.date(2019, 6, 10))
      self.assertEqual(cycle.start_date, datetime.date(2018, 6, 8))
      self.assertEqual(cycle.end_date, datetime.date(2018, 8, 9))
示例#7
0
    def test_type_casting(self):
        """Verify type casting for string input

    Test if string values get converted correctly to integers
    and arithmetic works"""

        annually_wf = {
            "title":
            "annually thingy",
            "description":
            "start this many a time",
            "frequency":
            "annually",
            "task_groups": [
                {
                    "title": "task group",
                    "task_group_tasks": [],
                    "task_group_objects": self.random_objects
                },
            ]
        }

        task = {
            'title': 'annual task 1',
            "relative_start_day": "10",  # 6/10/2015  Wed
            "relative_start_month": "6",
            "relative_end_day": "25",  # 6/25/2015 Thu
            "relative_end_month": "6",
        }
        with freezegun.freeze_time("2015-7-1 13:00"):
            _, wf = self.generator.generate_workflow(annually_wf)

            task_group = db.session.query(models.TaskGroup).filter(
                models.TaskGroup.workflow_id == wf.id).one()
            _, tgt = self.generator.generate_task_group_task(task_group,
                                                             data=task)

            _, awf = self.generator.activate_workflow(wf)

            active_wf = db.session.query(
                models.Workflow).filter(models.Workflow.id == wf.id).one()
            self.assertEqual(active_wf.status, "Active")
            self.assertEqual(active_wf.next_cycle_start_date,
                             datetime.date(2016, 6, 10))

        with freezegun.freeze_time("2016-6-10 13:00"):
            start_recurring_cycles()

            cycle = db.session.query(
                models.Cycle).filter(models.Cycle.workflow_id == wf.id).one()

            self.assertEqual(cycle.start_date, datetime.date(2016, 6, 10))
            self.assertEqual(cycle.end_date,
                             datetime.date(2016, 6, 24))  # 6/25/2015 is Sat
            self.assertEqual(active_wf.next_cycle_start_date,
                             datetime.date(2017, 6, 9))  # 6/10/2017 is Sat
示例#8
0
  def test_event_creation(self):
    """Test single event creation."""
    with freeze_time('2018-01-24'):
      start_recurring_cycles()

    events = models.Event.query.filter(models.Event.action == 'BULK').all()
    new_cycles_count = wf_models.Cycle.query.count()

    self.assertEqual(new_cycles_count, self.cycles_count + 2)
    self.assertEqual(len(events), 1)
    self.assertEqual(len(events[0].revisions), 28)
示例#9
0
    def test_event_creation(self):
        """Test single event creation."""
        with freeze_time('2018-01-24'):
            start_recurring_cycles()

        events = models.Event.query.filter(models.Event.action == 'BULK').all()
        new_cycles_count = wf_models.Cycle.query.count()

        self.assertEqual(new_cycles_count, self.cycles_count + 2)
        self.assertEqual(len(events), 1)
        self.assertEqual(len(events[0].revisions), 18)
示例#10
0
    def test_event_is_not_created(self):
        """Test no event created."""
        revisions_count = models.Revision.query.count()
        with freeze_time('2018-01-18'):
            start_recurring_cycles()

        events = models.Event.query.filter(models.Event.action == 'BULK').all()
        new_cycles_count = wf_models.Cycle.query.count()
        new_revisions_count = models.Revision.query.count()

        self.assertEqual(new_cycles_count, self.cycles_count)
        self.assertEqual(len(events), 0)
        self.assertEqual(new_revisions_count, revisions_count)
示例#11
0
  def test_event_is_not_created(self):
    """Test no event created."""
    revisions_count = models.Revision.query.count()
    with freeze_time('2018-01-18'):
      start_recurring_cycles()

    events = models.Event.query.filter(models.Event.action == 'BULK').all()
    new_cycles_count = wf_models.Cycle.query.count()
    new_revisions_count = models.Revision.query.count()

    self.assertEqual(new_cycles_count, self.cycles_count)
    self.assertEqual(len(events), 0)
    self.assertEqual(new_revisions_count, revisions_count)
示例#12
0
    def test_revisions(self, mock_mail):  # pylint: disable=unused-argument
        with freeze_time("2015-04-01"):
            _, workflow = self.wf_generator.generate_workflow(
                self.monthly_workflow)
            self.wf_generator.activate_workflow(workflow)
        event_count = Event.query.count()
        revision_query = Revision.query.filter_by(
            resource_type='CycleTaskGroupObjectTask', )
        revision_count = revision_query.count()
        # cycle starts on monday - 6th, and not on 5th
        with freeze_time("2015-04-03"):
            start_recurring_cycles()

        self.assertEqual(event_count + 1, Event.query.count())
        self.assertNotEqual(revision_count, revision_query.count())
示例#13
0
  def test_revisions(self, mock_mail):  # pylint: disable=unused-argument
    with freeze_time("2015-04-01"):
      _, workflow = self.wf_generator.generate_workflow(self.monthly_workflow)
      self.wf_generator.activate_workflow(workflow)
    event_count = Event.query.count()
    revision_query = Revision.query.filter_by(
        resource_type='CycleTaskGroupObjectTask',
    )
    revision_count = revision_query.count()
    # cycle starts on monday - 6th, and not on 5th
    with freeze_time("2015-04-03"):
      start_recurring_cycles()

    self.assertEqual(event_count + 1, Event.query.count())
    self.assertNotEqual(revision_count, revision_query.count())
示例#14
0
    def test_auto_generate_cycle(self, mock_mail):
        """Test auto recurring cycles"""

        with freeze_time("2015-04-01"):
            _, wf = self.wf_generator.generate_workflow(
                self.monthly_workflow_1)
            self.wf_generator.activate_workflow(wf)
            _, notif_data = common.get_daily_notifications()
            contact = self.person_1
            task_assignees = [contact, self.secondary_assignee]

            for user in task_assignees:
                self.assertNotIn(user.email, notif_data)

        with freeze_time("2015-04-02"):
            self.api.client.get("nightly_cron_endpoint")
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                self.assertNotIn(user.email, notif_data)
            start_recurring_cycles()
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                self.assertNotIn(user.email, notif_data)

        # cycle starts on monday - 6th, and not on 5th
        with freeze_time("2015-04-03"):
            from ggrc.login import noop
            noop.login()
            start_recurring_cycles()
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                self.assertIn(user.email, notif_data)

            # cycle started notifs available only for contact
            self.assertIn("cycle_started", notif_data[contact.email])

        with freeze_time("2015-04-15"):  # one day before due date
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                self.assertIn(user.email, notif_data)

        with freeze_time("2015-04-25"):  # due date
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                self.assertIn(user.email, notif_data)
示例#15
0
    def test_build_cycle_without_admin(self, logger):
        """Build Cycle without Workflow Admin."""
        workflow_setup_data = {
            "WORKFLOW_WITHOUT_ADMIN": tuple(),
            "WORKFLOW_WITH_ADMIN": (rbac_helper.GA_RNAME, )
        }
        with freezegun.freeze_time(datetime.date(2017, 9, 25)):
            for slug, wfa_g_rnames in workflow_setup_data.iteritems():
                with factories.single_commit():
                    workflow = self.setup_helper.setup_workflow(
                        wfa_g_rnames,
                        slug=slug,
                        repeat_every=1,
                        unit=all_models.Workflow.MONTH_UNIT,
                    )
                    task_group = wf_factories.TaskGroupFactory(
                        workflow=workflow)
                    wf_factories.TaskGroupTaskFactory(
                        task_group=task_group,
                        start_date=datetime.date(2017, 9, 26),
                        end_date=datetime.date(2017, 9, 30),
                    )
                self.api_helper.put(
                    workflow, {
                        "status":
                        "Active",
                        "recurrences":
                        bool(workflow.repeat_every and workflow.unit)
                    })

        with freezegun.freeze_time(datetime.date(2017, 10, 25)):
            start_recurring_cycles()

        workflow_without_admin = all_models.Workflow.query.filter_by(
            slug="WORKFLOW_WITHOUT_ADMIN").one()
        self.assertEqual(len(workflow_without_admin.cycles), 0)
        logger.error.assert_called_once_with(
            "Cannot start cycle on Workflow with slug == '%s' and id == '%s', "
            "cause it doesn't have Admins", workflow_without_admin.slug,
            workflow_without_admin.id)

        workflow_with_admin = all_models.Workflow.query.filter_by(
            slug="WORKFLOW_WITH_ADMIN").one()
        self.assertEqual(len(workflow_with_admin.cycles), 1)
示例#16
0
  def test_build_cycle_without_admin(self, logger):
    """Build Cycle without Workflow Admin."""
    workflow_setup_data = {
        "WORKFLOW_WITHOUT_ADMIN": tuple(),
        "WORKFLOW_WITH_ADMIN": (rbac_helper.GA_RNAME, )
    }
    with freezegun.freeze_time(datetime.date(2017, 9, 25)):
      for slug, wfa_g_rnames in workflow_setup_data.iteritems():
        with factories.single_commit():
          workflow = self.setup_helper.setup_workflow(
              wfa_g_rnames,
              slug=slug,
              repeat_every=1,
              unit=all_models.Workflow.MONTH_UNIT,
          )
          task_group = wf_factories.TaskGroupFactory(workflow=workflow)
          wf_factories.TaskGroupTaskFactory(
              task_group=task_group,
              start_date=datetime.date(2017, 9, 26),
              end_date=datetime.date(2017, 9, 30),
          )
        self.api_helper.put(workflow, {
            "status": "Active",
            "recurrences": bool(workflow.repeat_every and workflow.unit)
        })

    with freezegun.freeze_time(datetime.date(2017, 10, 25)):
      start_recurring_cycles()

    workflow_without_admin = all_models.Workflow.query.filter_by(
        slug="WORKFLOW_WITHOUT_ADMIN").one()
    self.assertEqual(len(workflow_without_admin.cycles), 0)
    logger.error.assert_called_once_with(
        "Cannot start cycle on Workflow with slug == '%s' and id == '%s', "
        "cause it doesn't have Admins",
        workflow_without_admin.slug, workflow_without_admin.id)

    workflow_with_admin = all_models.Workflow.query.filter_by(
        slug="WORKFLOW_WITH_ADMIN").one()
    self.assertEqual(len(workflow_with_admin.cycles), 1)
    def test_past_cycle(self):
        """Past workflow

    We create & activate our workflow on Friday and create a workflow
    with one task with start date on Monday and ending on
    Wednesday and second task starting on Tuesday and ending on Thursday.

    Because it's Friday, created cycles should be in the next week.
    """
        weekly_wf = {
            "title":
            "weekly thingy",
            "description":
            "start this many a time",
            "frequency":
            "weekly",
            "task_groups": [
                {
                    "title":
                    "tg_2",
                    "task_group_tasks": [
                        {
                            'title': 'weekly task 1',
                            "relative_start_day": 1,  # Monday, 8th
                            "relative_start_month": None,
                            "relative_end_day": 3,  # Wednesday, 10th
                            "relative_end_month": None,
                        },
                        {
                            'title': 'weekly task 2',
                            "relative_start_day": 2,  # Tuesday, 9th
                            "relative_start_month": None,
                            "relative_end_day": 4,  # 11th, Thursday
                            "relative_end_month": None,
                        }
                    ],
                    "task_group_objects":
                    self.random_objects
                },
            ]
        }

        with freezegun.freeze_time("2015-6-12 13:00:00"):  # Friday, 6/12/2015
            _, wf = self.generator.generate_workflow(weekly_wf)
            _, tg = self.generator.generate_task_group(wf)
            _, awf = self.generator.activate_workflow(wf)

            active_wf = db.session.query(
                models.Workflow).filter(models.Workflow.id == wf.id).one()
            self.assertEqual(active_wf.status, "Active")
            self.assertEqual(active_wf.next_cycle_start_date,
                             datetime.date(2015, 6, 15))

        with freezegun.freeze_time("2015-6-15 13:00:00"):
            start_recurring_cycles()
            cycle = db.session.query(models.Cycle).filter(
                models.Cycle.workflow_id == wf.id,
                models.Cycle.start_date == datetime.date(2015, 6, 15)).one()

            self.assertEqual(cycle.start_date, datetime.date(2015, 6, 15))
            self.assertEqual(cycle.end_date, datetime.date(2015, 6, 18))

            # Next cycle should start next Tuesday
            self.assertEqual(active_wf.next_cycle_start_date,
                             datetime.date(2015, 6, 22))

        with freezegun.freeze_time("2015-6-22 14:00"):
            start_recurring_cycles()
            active_wf = db.session.query(
                models.Workflow).filter(models.Workflow.id == wf.id).one()
            self.assertEqual(active_wf.next_cycle_start_date,
                             datetime.date(2015, 6, 29))

            cycle = db.session.query(models.Cycle).filter(
                models.Cycle.workflow_id == wf.id,
                models.Cycle.start_date == datetime.date(2015, 6, 22)).one()

            self.assertEqual(cycle.start_date, datetime.date(2015, 6, 22))
            self.assertEqual(cycle.end_date, datetime.date(2015, 6, 25))
    def test_future_cycle(self):
        """Future cycle workflow

    We create & activate our workflow on Monday and create a workflow
    with one task with start date on Tuesday (tomorrow) and ending on
    Thursday and second task starting on Wednesday and ending on Monday
    (next week).

    Cycle should be generated for the future.
    """
        weekly_wf = {
            "title":
            "weekly thingy",
            "description":
            "start this many a time",
            "frequency":
            "weekly",
            "task_groups": [
                {
                    "title":
                    "tg_2",
                    "task_group_tasks": [
                        {
                            'title': 'weekly task 1',
                            "relative_start_day": 2,  # Tuesday, 9th
                            "relative_start_month": None,
                            "relative_end_day": 4,  # Thursday, 11th
                            "relative_end_month": None,
                        },
                        {
                            'title': 'weekly task 2',
                            "relative_start_day": 3,  # Wednesday, 10th
                            "relative_start_month": None,
                            "relative_end_day": 1,  # 15th, Monday
                            "relative_end_month": None,
                        }
                    ],
                    "task_group_objects":
                    self.random_objects
                },
            ]
        }

        with freezegun.freeze_time("2015-6-8 13:00:00"):  # Monday, 6/8/2015
            _, wf = self.generator.generate_workflow(weekly_wf)
            _, tg = self.generator.generate_task_group(wf)
            _, awf = self.generator.activate_workflow(wf)

            active_wf = db.session.query(
                models.Workflow).filter(models.Workflow.id == wf.id).one()
            self.assertEqual(active_wf.status, "Active")
            self.assertEqual(active_wf.next_cycle_start_date,
                             datetime.date(2015, 6, 9))

            cycles = db.session.query(models.Cycle).filter(
                models.Cycle.workflow_id == wf.id,
                models.Cycle.start_date > datetime.date(2015, 6, 7))

            self.assertEqual(cycles.count(), 0)

        with freezegun.freeze_time("2015-6-9 13:00:00"):
            start_recurring_cycles()

            cycle = db.session.query(models.Cycle).filter(
                models.Cycle.workflow_id == wf.id,
                models.Cycle.start_date == datetime.date(2015, 6, 9)).one()

            self.assertEqual(cycle.start_date, datetime.date(2015, 6, 9))
            self.assertEqual(cycle.end_date, datetime.date(2015, 6, 15))
            self.assertEqual(active_wf.next_cycle_start_date,
                             datetime.date(2015, 6, 16))

        with freezegun.freeze_time("2015-6-16 13:00:00"):
            start_recurring_cycles()

            cycle = db.session.query(models.Cycle).filter(
                models.Cycle.workflow_id == wf.id,
                models.Cycle.start_date == datetime.date(2015, 6, 16)).one()

            self.assertEqual(cycle.start_date, datetime.date(2015, 6, 16))
            self.assertEqual(cycle.end_date, datetime.date(2015, 6, 22))
            self.assertEqual(active_wf.next_cycle_start_date,
                             datetime.date(2015, 6, 23))
  def test_mid_cycle(self):
    """Mid-cycle workflow

    We create & activate our workflow on Wednesday and create a workflow
    with one task with start date on Tuesday (yesterday) and ending on
    Thursday and second task starting on Wednesday and ending on Monday
    (next week).

    Because it's Wednesday, workflow should be activated immediately.
    """
    weekly_wf = {
        "title": "weekly thingy",
        "description": "start this many a time",
        "frequency": "weekly",
        "task_groups": [{
            "title": "tg_2",
            "task_group_tasks": [
                {
                    'title': 'weekly task 1',
                    "relative_start_day": 2,  # Tuesday, 9th
                    "relative_start_month": None,
                    "relative_end_day": 4,  # Thursday, 11th
                    "relative_end_month": None,
                },
                {
                    'title': 'weekly task 2',
                    "relative_start_day": 3,  # Wednesday, 10th
                    "relative_start_month": None,
                    "relative_end_day": 1,  # 15th, Monday
                    "relative_end_month": None,
                }
            ],
            "task_group_objects": self.random_objects
        },
        ]
    }

    with freezegun.freeze_time("2015-6-10 13:00:00"):  # Wednesday, 6/10/2015
      _, wf = self.generator.generate_workflow(weekly_wf)
      _, tg = self.generator.generate_task_group(wf)
      _, awf = self.generator.activate_workflow(wf)

      active_wf = db.session.query(models.Workflow).filter(
          models.Workflow.id == wf.id).one()
      self.assertEqual(active_wf.status, "Active")
      # Originally this would be 2015-6-10 but because update_workflow_state
      # fixes workflow next_cycle_start_date it's actually 16
      self.assertEqual(active_wf.next_cycle_start_date,
                       datetime.date(2015, 6, 16))

      cycle = db.session.query(models.Cycle).filter(
          models.Cycle.workflow_id == wf.id).one()

      # Start date should be Tuesday 9th (yesterday), end date should be Monday
      # 15h
      self.assertEqual(cycle.start_date, datetime.date(2015, 6, 9))
      self.assertEqual(cycle.end_date, datetime.date(2015, 6, 15))

    with freezegun.freeze_time("2015-6-16 13:00:00"):  # Wednesday, 6/10/2015
      start_recurring_cycles()
      active_wf = db.session.query(models.Workflow).filter(
          models.Workflow.id == wf.id).one()
      self.assertEqual(active_wf.next_cycle_start_date,
                       datetime.date(2015, 6, 23))

      cycle = db.session.query(models.Cycle).filter(
          models.Cycle.workflow_id == wf.id,
          models.Cycle.start_date > datetime.date(2015, 6, 15)).one()

      self.assertEqual(cycle.start_date, datetime.date(2015, 6, 16))
      self.assertEqual(cycle.end_date, datetime.date(2015, 6, 22))
  def test_past_cycle(self):
    """Past workflow

    We create & activate our workflow on Friday and create a workflow
    with one task with start date on Monday and ending on
    Wednesday and second task starting on Tuesday and ending on Thursday.

    Because it's Friday, created cycles should be in the next week.
    """
    weekly_wf = {
        "title": "weekly thingy",
        "description": "start this many a time",
        "frequency": "weekly",
        "task_groups": [{
            "title": "tg_2",
            "task_group_tasks": [
                {
                    'title': 'weekly task 1',
                    "relative_start_day": 1,  # Monday, 8th
                    "relative_start_month": None,
                    "relative_end_day": 3,  # Wednesday, 10th
                    "relative_end_month": None,
                },
                {
                    'title': 'weekly task 2',
                    "relative_start_day": 2,  # Tuesday, 9th
                    "relative_start_month": None,
                    "relative_end_day": 4,  # 11th, Thursday
                    "relative_end_month": None,
                }
            ],
            "task_group_objects": self.random_objects
        },
        ]
    }

    with freezegun.freeze_time("2015-6-12 13:00:00"):  # Friday, 6/12/2015
      _, wf = self.generator.generate_workflow(weekly_wf)
      _, tg = self.generator.generate_task_group(wf)
      _, awf = self.generator.activate_workflow(wf)

      active_wf = db.session.query(models.Workflow).filter(
          models.Workflow.id == wf.id).one()
      self.assertEqual(active_wf.status, "Active")
      self.assertEqual(active_wf.next_cycle_start_date,
                       datetime.date(2015, 6, 15))

    with freezegun.freeze_time("2015-6-15 13:00:00"):
      start_recurring_cycles()
      cycle = db.session.query(models.Cycle).filter(
          models.Cycle.workflow_id == wf.id,
          models.Cycle.start_date == datetime.date(2015, 6, 15)).one()

      self.assertEqual(cycle.start_date, datetime.date(2015, 6, 15))
      self.assertEqual(cycle.end_date, datetime.date(2015, 6, 18))

      # Next cycle should start next Tuesday
      self.assertEqual(active_wf.next_cycle_start_date,
                       datetime.date(2015, 6, 22))

    with freezegun.freeze_time("2015-6-22 14:00"):
      start_recurring_cycles()
      active_wf = db.session.query(models.Workflow).filter(
          models.Workflow.id == wf.id).one()
      self.assertEqual(active_wf.next_cycle_start_date,
                       datetime.date(2015, 6, 29))

      cycle = db.session.query(models.Cycle).filter(
          models.Cycle.workflow_id == wf.id,
          models.Cycle.start_date == datetime.date(2015, 6, 22)).one()

      self.assertEqual(cycle.start_date, datetime.date(2015, 6, 22))
      self.assertEqual(cycle.end_date, datetime.date(2015, 6, 25))
  def test_future_cycle(self):
    """Future cycle workflow

    We create & activate our workflow on Monday and create a workflow
    with one task with start date on Tuesday (tomorrow) and ending on
    Thursday and second task starting on Wednesday and ending on Monday
    (next week).

    Cycle should be generated for the future.
    """
    weekly_wf = {
        "title": "weekly thingy",
        "description": "start this many a time",
        "frequency": "weekly",
        "task_groups": [{
            "title": "tg_2",
            "task_group_tasks": [
                {
                    'title': 'weekly task 1',
                    "relative_start_day": 2,  # Tuesday, 9th
                    "relative_start_month": None,
                    "relative_end_day": 4,  # Thursday, 11th
                    "relative_end_month": None,
                },
                {
                    'title': 'weekly task 2',
                    "relative_start_day": 3,  # Wednesday, 10th
                    "relative_start_month": None,
                    "relative_end_day": 1,  # 15th, Monday
                    "relative_end_month": None,
                }
            ],
            "task_group_objects": self.random_objects
        },
        ]
    }

    with freezegun.freeze_time("2015-6-8 13:00:00"):  # Monday, 6/8/2015
      _, wf = self.generator.generate_workflow(weekly_wf)
      _, tg = self.generator.generate_task_group(wf)
      _, awf = self.generator.activate_workflow(wf)

      active_wf = db.session.query(models.Workflow).filter(
          models.Workflow.id == wf.id).one()
      self.assertEqual(active_wf.status, "Active")
      self.assertEqual(active_wf.next_cycle_start_date,
                       datetime.date(2015, 6, 9))

      cycles = db.session.query(models.Cycle).filter(
          models.Cycle.workflow_id == wf.id,
          models.Cycle.start_date > datetime.date(2015, 6, 7))

      self.assertEqual(cycles.count(), 0)

    with freezegun.freeze_time("2015-6-9 13:00:00"):
      start_recurring_cycles()

      cycle = db.session.query(models.Cycle).filter(
          models.Cycle.workflow_id == wf.id,
          models.Cycle.start_date == datetime.date(2015, 6, 9)).one()

      self.assertEqual(cycle.start_date, datetime.date(2015, 6, 9))
      self.assertEqual(cycle.end_date, datetime.date(2015, 6, 15))
      self.assertEqual(active_wf.next_cycle_start_date,
                       datetime.date(2015, 6, 16))

    with freezegun.freeze_time("2015-6-16 13:00:00"):
      start_recurring_cycles()

      cycle = db.session.query(models.Cycle).filter(
          models.Cycle.workflow_id == wf.id,
          models.Cycle.start_date == datetime.date(2015, 6, 16)).one()

      self.assertEqual(cycle.start_date, datetime.date(2015, 6, 16))
      self.assertEqual(cycle.end_date, datetime.date(2015, 6, 22))
      self.assertEqual(active_wf.next_cycle_start_date,
                       datetime.date(2015, 6, 23))
    def test_mid_cycle(self):
        """Mid-cycle workflow

    We create & activate our workflow on Wednesday and create a workflow
    with one task with start date on Tuesday (yesterday) and ending on
    Thursday and second task starting on Wednesday and ending on Monday
    (next week).

    Because it's Wednesday, workflow should be activated immediately.
    """
        weekly_wf = {
            "title":
            "weekly thingy",
            "description":
            "start this many a time",
            "frequency":
            "weekly",
            "task_groups": [
                {
                    "title":
                    "tg_2",
                    "task_group_tasks": [
                        {
                            'title': 'weekly task 1',
                            "relative_start_day": 2,  # Tuesday, 9th
                            "relative_start_month": None,
                            "relative_end_day": 4,  # Thursday, 11th
                            "relative_end_month": None,
                        },
                        {
                            'title': 'weekly task 2',
                            "relative_start_day": 3,  # Wednesday, 10th
                            "relative_start_month": None,
                            "relative_end_day": 1,  # 15th, Monday
                            "relative_end_month": None,
                        }
                    ],
                    "task_group_objects":
                    self.random_objects
                },
            ]
        }

        with freezegun.freeze_time(
                "2015-6-10 13:00:00"):  # Wednesday, 6/10/2015
            _, wf = self.generator.generate_workflow(weekly_wf)
            _, tg = self.generator.generate_task_group(wf)
            _, awf = self.generator.activate_workflow(wf)

            active_wf = db.session.query(
                models.Workflow).filter(models.Workflow.id == wf.id).one()
            self.assertEqual(active_wf.status, "Active")
            # Originally this would be 2015-6-10 but because update_workflow_state
            # fixes workflow next_cycle_start_date it's actually 16
            self.assertEqual(active_wf.next_cycle_start_date,
                             datetime.date(2015, 6, 16))

            cycle = db.session.query(
                models.Cycle).filter(models.Cycle.workflow_id == wf.id).one()

            # Start date should be Tuesday 9th (yesterday), end date should be Monday
            # 15h
            self.assertEqual(cycle.start_date, datetime.date(2015, 6, 9))
            self.assertEqual(cycle.end_date, datetime.date(2015, 6, 15))

        with freezegun.freeze_time(
                "2015-6-16 13:00:00"):  # Wednesday, 6/10/2015
            start_recurring_cycles()
            active_wf = db.session.query(
                models.Workflow).filter(models.Workflow.id == wf.id).one()
            self.assertEqual(active_wf.next_cycle_start_date,
                             datetime.date(2015, 6, 23))

            cycle = db.session.query(models.Cycle).filter(
                models.Cycle.workflow_id == wf.id,
                models.Cycle.start_date > datetime.date(2015, 6, 15)).one()

            self.assertEqual(cycle.start_date, datetime.date(2015, 6, 16))
            self.assertEqual(cycle.end_date, datetime.date(2015, 6, 22))