Пример #1
0
  def test_delete_activated_workflow(self, mock_mail):

    with freeze_time("2015-02-01 13:39:20"):
      _, workflow = self.wf_generator.generate_workflow(self.quarterly_wf_1)
      response, workflow = self.wf_generator.activate_workflow(workflow)

      self.assert200(response)

      user = Person.query.get(self.user.id)

    with freeze_time("2015-01-01 13:39:20"):
      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(user.email, notif_data)

    with freeze_time("2015-01-29 13:39:20"):
      _, notif_data = common.get_daily_notifications()
      self.assertIn(user.email, notif_data)
      self.assertIn("cycle_starts_in", notif_data[user.email])

      workflow = Workflow.query.get(workflow.id)

      response = self.wf_generator.api.delete(workflow)
      self.assert200(response)

      _, notif_data = common.get_daily_notifications()
      user = Person.query.get(self.user.id)

      self.assertNotIn(user.email, notif_data)
Пример #2
0
  def test_start_failed(self, mock_mail):

    wf_admin = "*****@*****.**"

    with freeze_time("2015-02-01 13:39:20"):
      _, wf = self.wf_generator.generate_workflow(self.quarterly_wf)
      response, wf = self.wf_generator.activate_workflow(wf)
      print wf.next_cycle_start_date

      self.assert200(response)

    with freeze_time("2015-01-01 13:39:20"):
      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(wf_admin, notif_data)

    with freeze_time("2015-01-29 13:39:20"):
      _, notif_data = common.get_daily_notifications()
      self.assertIn(wf_admin, notif_data)
      self.assertIn("cycle_starts_in", notif_data[wf_admin])

    with freeze_time("2015-03-05 13:39:20"):
      _, notif_data = common.get_daily_notifications()
      self.assertIn(wf_admin, notif_data)
      self.assertNotIn("cycle_started", notif_data[wf_admin])
      self.assertIn(wf_admin, notif_data)
      self.assertIn("cycle_start_failed", notif_data[wf_admin])

      common.send_daily_digest_notifications()

      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(wf_admin, notif_data)
Пример #3
0
  def test_one_time_wf(self):
    # setup
    with freeze_time("2015-04-07 03:21:34"):
      wf_response, wf = self.wf_generator.generate_workflow(data={
          # admin will be the current user
          "notify_on_change": True,  # force real time updates
          "title": "One-time WF",
          "notify_custom_message": textwrap.dedent("""\
              Hi all.
              Did you know that Irelnd city namd Newtownmountkennedy has 19
              letters? But it's not the longest one. The recordsman is the
              city in New Zealand that contains 97 letter."""),
      })

      _, tg = self.wf_generator.generate_task_group(wf, data={
          "title": "TG #1 for the One-time WF",
          "contact": self.short_dict(self.tgassignee1, "people"),
      })

      self.wf_generator.generate_task_group_task(tg, {
          "title": "task #1 for one-time workflow",
          "contact": self.short_dict(self.member1, "people"),
          "start_date": "04/07/2015",
          "end_date": "04/15/2015",
      })

      self.wf_generator.generate_task_group_object(tg, self.random_objects[0])
      self.wf_generator.generate_task_group_object(tg, self.random_objects[1])

    # test
    with freeze_time("2015-04-07 03:21:34"):
      cycle_response, cycle = self.wf_generator.generate_cycle(wf)
      self.wf_generator.activate_workflow(wf)

      common.get_daily_notifications()
Пример #4
0
  def test_force_one_wf_notifications(self, mock_mail):

    with freeze_time("2015-02-01 13:39:20"):
      _, wf_forced = self.wf_generator.generate_workflow(
          self.quarterly_wf_forced)
      response, wf_forced = self.wf_generator.activate_workflow(wf_forced)
      _, wf = self.wf_generator.generate_workflow(self.quarterly_wf)
      response, wf = self.wf_generator.activate_workflow(wf)

      self.assert200(response)

      user = models.Person.query.get(self.user.id)

    with freeze_time("2015-01-29 13:39:20"):
      _, notif_data = common.get_daily_notifications()
      self.assertIn(user.email, notif_data)
      self.assertIn("cycle_starts_in", notif_data[user.email])
      self.assertIn(wf_forced.id, notif_data[user.email]["cycle_starts_in"])
      self.assertIn(wf.id, notif_data[user.email]["cycle_starts_in"])

      self.object_generator.generate_notification_setting(
          self.user.id, "Email_Digest", False)

      user = models.Person.query.get(self.user.id)
      _, notif_data = common.get_daily_notifications()
      self.assertIn(user.email, notif_data)
      self.assertIn("cycle_starts_in", notif_data[user.email])
      self.assertIn(wf_forced.id, notif_data[user.email]["cycle_starts_in"])
      self.assertNotIn(wf.id, notif_data[user.email]["cycle_starts_in"])
Пример #5
0
  def test_one_time_wf_activate(self):
    def get_person(person_id):
      return db.session.query(Person).filter(Person.id == person_id).one()
    with freeze_time("2015-04-10"):
      _, wf = self.wf_generator.generate_workflow(self.one_time_workflow_1)

      _, cycle = self.wf_generator.generate_cycle(wf)
      self.wf_generator.activate_workflow(wf)

      person_2 = get_person(self.random_people[2].id)

    with freeze_time("2015-04-11"):
      _, notif_data = common.get_daily_notifications()
      self.assertIn(person_2.email, notif_data)
      self.assertIn("cycle_started", notif_data[person_2.email])
      self.assertIn(cycle.id, notif_data[person_2.email]["cycle_started"])
      self.assertIn("my_tasks",
                    notif_data[person_2.email]["cycle_data"][cycle.id])

      person_1 = get_person(self.random_people[0].id)

    with freeze_time("2015-05-03"):  # two days befor due date
      _, notif_data = common.get_daily_notifications()
      self.assertIn(person_1.email, notif_data)
      self.assertNotIn("due_in", notif_data[person_1.email])
      self.assertNotIn("due_today", notif_data[person_1.email])

    with freeze_time("2015-05-04"):  # one day befor due date
      _, notif_data = common.get_daily_notifications()
      self.assertEqual(len(notif_data[person_1.email]["due_in"]), 1)

    with freeze_time("2015-05-05"):  # due date
      _, notif_data = common.get_daily_notifications()
      self.assertEqual(len(notif_data[person_1.email]["due_today"]), 1)
  def test_multiply_mapping(self):
    """Test notification for multiply mapping"""
    controls = [factories.ControlFactory() for _ in xrange(5)]
    snapshots = self._create_snapshots(self.assessment.audit, controls)

    def get_relation_dict(destination_obj):
      return {
          "relationship": {
              "context": {"id": self.assessment.audit.context.id,
                          "type": self.assessment.audit.context.type},
              "source": {"id": self.assessment.id,
                         "type": self.assessment.type},
              "destination": {"id": destination_obj.id,
                              "type": destination_obj.type}
          }
      }
    notifs, _ = common.get_daily_notifications()
    self.assertFalse(len(notifs))
    self.assessment.status = "In Progress"
    post_data = [get_relation_dict(s) for s in snapshots]
    db.session.add(self.assessment)
    resp = self.api.send_request(
        self.api.client.post, obj=all_models.Relationship, data=post_data)
    self.assert200(resp)
    notifs, _ = common.get_daily_notifications()
    self.assertEqual(len(notifs), 1)
  def test_sending_overdue_notifications_for_tasks(self, is_vf_needed, _):
    """Overdue notifications should be sent for overdue tasks every day.

    Even if an overdue notification has already been sent, it should still be
    sent in every following daily digest f a task is still overdue.
    """
    with freeze_time("2017-05-15 14:25:36"):
      tmp = self.one_time_workflow.copy()
      tmp['is_verification_needed'] = is_vf_needed
      _, workflow = self.wf_generator.generate_workflow(tmp)
      self.wf_generator.generate_cycle(workflow)
      response, workflow = self.wf_generator.activate_workflow(workflow)
      self.assert200(response)

    tasks = workflow.cycles[0].cycle_task_group_object_tasks
    task1_id = tasks[0].id
    task2_id = tasks[1].id

    user = models.Person.query.get(self.user.id)

    with freeze_time("2017-05-14 08:09:10"):
      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user.email, {})
      self.assertNotIn("task_overdue", user_notifs)

    with freeze_time("2017-05-15 08:09:10"):  # task 1 due date
      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user.email, {})
      self.assertNotIn("task_overdue", user_notifs)

    with freeze_time("2017-05-16 08:09:10"):  # task 2 due date
      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user.email, {})
      self.assertIn("task_overdue", user_notifs)

      overdue_task_ids = sorted(user_notifs["task_overdue"].keys())
      self.assertEqual(overdue_task_ids, [task1_id])

    with freeze_time("2017-05-17 08:09:10"):  # after both tasks' due dates
      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user.email, {})
      self.assertIn("task_overdue", user_notifs)

      overdue_task_ids = sorted(user_notifs["task_overdue"].keys())
      self.assertEqual(overdue_task_ids, [task1_id, task2_id])

      common.send_daily_digest_notifications()

    # even after sending the overdue notifications, they are sent again the
    # day after, too
    with freeze_time("2017-05-18 08:09:10"):
      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user.email, {})
      self.assertIn("task_overdue", user_notifs)

      overdue_task_ids = sorted(user_notifs["task_overdue"].keys())
      self.assertEqual(overdue_task_ids, [task1_id, task2_id])
  def test_move_end_date_to_today(self, mock_mail):
    def get_person(person_id):
      return db.session.query(Person).filter(Person.id == person_id).one()

    with freeze_time("2015-04-10 03:21:34"):
      _, workflow = self.wf_generator.generate_workflow(
          self.one_time_workflow_1)

      _, cycle = self.wf_generator.generate_cycle(workflow)
      self.wf_generator.activate_workflow(workflow)

    with freeze_time("2015-05-02 03:21:34"):
      common.send_daily_digest_notifications()
      _, notif_data = common.get_daily_notifications()
      self.assertEqual(notif_data, {})

      # one email to owner and one to assigne
      self.assertEqual(mock_mail.call_count, 2)

    with freeze_time("2015-05-03 03:21:34"):
      cycle = Cycle.query.get(cycle.id)
      task1 = CycleTaskGroupObjectTask.query.get(
          cycle.cycle_task_group_object_tasks[0].id)
      task2 = CycleTaskGroupObjectTask.query.get(
          cycle.cycle_task_group_object_tasks[1].id)

      self.wf_generator.modify_object(
          task1, data={"end_date": date(2015, 5, 3)})
      self.wf_generator.modify_object(
          task2, data={"end_date": date(2015, 5, 4)})

    with freeze_time("2015-05-03 03:21:34"):  # one day befor due date
      user = get_person(self.user.id)
      _, notif_data = common.get_daily_notifications()

      self.assertNotEquals(notif_data, {})
      self.assertIn(user.email, notif_data)
      self.assertIn("due_today", notif_data[user.email])
      self.assertIn("due_in", notif_data[user.email])
      self.assertEqual(len(notif_data[user.email]["due_today"]), 1)

      common.send_daily_digest_notifications()

    with freeze_time("2015-05-04 03:21:34"):  # due date
      user = get_person(self.user.id)
      _, notif_data = common.get_daily_notifications()
      self.assertIn(user.email, notif_data)
      self.assertIn("due_today", notif_data[user.email])
      self.assertNotIn("due_in", notif_data[user.email])
      common.send_daily_digest_notifications()

    with freeze_time("2015-05-05 03:21:34"):  # due date
      _, notif_data = common.get_daily_notifications()
      self.assertEqual(notif_data, {})
Пример #9
0
  def test_adjust_overdue_notifications_on_task_status_change(self,
                                                              is_vf_needed,
                                                              _):
    """Sending overdue notifications should take task status into account."""
    with freeze_time("2017-05-15 14:25:36"):
      tmp = self.one_time_workflow.copy()
      tmp['is_verification_needed'] = is_vf_needed
      _, workflow = self.wf_generator.generate_workflow(tmp)
      self.wf_generator.generate_cycle(workflow)
      response, workflow = self.wf_generator.activate_workflow(workflow)
      self.assert200(response)

      tasks = workflow.cycles[0].cycle_task_group_object_tasks
      task1, task2 = tasks
      self.wf_generator.modify_object(task2, {"end_date": date(2099, 12, 31)})

      user = models.Person.query.get(self.user.id)
      user_email = user.email
    if is_vf_needed:
      non_final_states = [CycleTaskGroupObjectTask.ASSIGNED,
                          CycleTaskGroupObjectTask.IN_PROGRESS,
                          CycleTaskGroupObjectTask.FINISHED,
                          CycleTaskGroupObjectTask.DECLINED]
      final_state = CycleTaskGroupObjectTask.VERIFIED
    else:
      non_final_states = [CycleTaskGroupObjectTask.ASSIGNED,
                          CycleTaskGroupObjectTask.IN_PROGRESS]
      final_state = CycleTaskGroupObjectTask.FINISHED

    with freeze_time("2017-05-16 08:09:10"):  # a day after task1 due date
      for state in non_final_states:
        # clear all notifications before before changing the task status
        models.Notification.query.delete()
        _, notif_data = common.get_daily_notifications()
        self.assertEqual(notif_data, {})

        self.wf_generator.modify_object(task1, {"status": state})

        _, notif_data = common.get_daily_notifications()
        user_notifs = notif_data.get(user_email, {})
        self.assertIn("task_overdue", user_notifs)
        self.assertEqual(len(user_notifs["task_overdue"]), 1)

      # WITHOUT clearing the overdue notifications, move the task to "verified"
      # state, and the overdue notification should disappear.

      self.wf_generator.modify_object(task1, {"status": final_state})
      common.generate_cycle_tasks_notifs()
      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user_email, {})
      self.assertNotIn("task_overdue", user_notifs)
Пример #10
0
  def test_assessment_inprogress_reminder_finish_afterwards(self):
    """Tests that notifications don't get sent if Finished already.

    Tests that notifications don't get sent out if assessment has been moved to
    `Finished` state since reminder was activated.
    """
    # pylint: disable=invalid-name

    with freeze_time("2015-04-01 17:13:15"):
      assessment = self.create_assessment()

      assessment = self.change_status(assessment,
                                      models.Assessment.PROGRESS_STATE)

      self.send_reminder(assessment)

      notifications = self._get_notifications(
          False, "assessment_assignees_reminder",
      ).all()
      self.assertEqual(len(notifications), 1)

      notif = notifications[0]
      revisions = models.Revision.query.filter_by(resource_type='Notification',
                                                  resource_id=notif.id).count()
      self.assertEqual(revisions, 1)

      self.change_status(assessment, models.Assessment.DONE_STATE)

      _, notif_data = common.get_daily_notifications()
      self.assertEqual(notif_data, {})
Пример #11
0
  def test_ca_change_by_import(self):
    """Test notification when custom attribute value is changed by import"""

    with factories.single_commit():
      assessment = factories.AssessmentFactory(status="Completed")
      factories.CustomAttributeDefinitionFactory(
          definition_type="assessment",
          title="Test GCAD",
      )
      assessment_slug = assessment.slug
      assessment_id = assessment.id
      user = all_models.Person.query.filter_by(
          email="*****@*****.**").first()
      assessment.add_person_with_role_name(user, "Assignees")

    from flask import g
    setattr(g, '_current_user', user)

    import_data = OrderedDict([
        ("object_type", "Assessment"),
        ("Code*", assessment_slug),
        ("Test GCAD", "test value"),
    ])
    response = self.import_data(import_data)
    self._check_csv_response(response, {})

    notifs, _ = common.get_daily_notifications()

    self.assertEqual(len(notifs), 2)
    assessment = all_models.Assessment.query.get(assessment_id)
    cad = assessment.get_custom_attribute_definitions().filter_by(
        title="Test GCAD").first()
    self.assertEqual(
        [i.attribute_value for i in cad.attribute_values], ["test value"])
Пример #12
0
  def test_default_notifications_settings(self, mock_mail):

    with freeze_time("2015-02-01 13:39:20"):
      _, wf = self.wf_generator.generate_workflow(self.quarterly_wf)
      response, wf = self.wf_generator.activate_workflow(wf)

      self.assert200(response)

      user = models.Person.query.get(self.user.id)

    with freeze_time("2015-01-01 13:39:20"):
      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(user.email, notif_data)

    with freeze_time("2015-01-29 13:39:20"):
      _, notif_data = common.get_daily_notifications()
      self.assertIn(user.email, notif_data)
Пример #13
0
  def test_one_time_wf_activate_single_person(self, mock_mail):

    with freeze_time("2015-04-10"):
      user = "******"
      _, wf = self.wf_generator.generate_workflow(
          self.one_time_workflow_single_person)

      _, cycle = self.wf_generator.generate_cycle(wf)
      self.wf_generator.activate_workflow(wf)

    with freeze_time("2015-04-11"):
      _, notif_data = common.get_daily_notifications()
      self.assertIn("cycle_started", notif_data[user])
      self.assertIn(cycle.id, notif_data[user]["cycle_started"])
      self.assertIn("my_tasks", notif_data[user]["cycle_data"][cycle.id])
      self.assertIn("cycle_tasks", notif_data[user]["cycle_data"][cycle.id])
      self.assertIn(
          "my_task_groups", notif_data[user]["cycle_data"][cycle.id])
      self.assertIn("cycle_url", notif_data[user]["cycle_started"][cycle.id])

      cycle = Cycle.query.get(cycle.id)
      cycle_data = notif_data[user]["cycle_data"][cycle.id]
      for task in cycle.cycle_task_group_object_tasks:
        self.assertIn(task.id, cycle_data["my_tasks"])
        self.assertIn(task.id, cycle_data["cycle_tasks"])
        self.assertIn("title", cycle_data["my_tasks"][task.id])
        self.assertIn("title", cycle_data["cycle_tasks"][task.id])
        self.assertIn("cycle_task_url", cycle_data["cycle_tasks"][task.id])

    with freeze_time("2015-05-03"):  # two days before due date
      _, notif_data = common.get_daily_notifications()
      self.assertIn(user, notif_data)
      self.assertNotIn("due_in", notif_data[user])
      self.assertNotIn("due_today", notif_data[user])

    with freeze_time("2015-05-04"):  # one day before due date
      _, notif_data = common.get_daily_notifications()
      self.assertEqual(len(notif_data[user]["due_in"]), 2)

    with freeze_time("2015-05-05"):  # due date
      _, notif_data = common.get_daily_notifications()
      self.assertEqual(len(notif_data[user]["due_today"]), 2)

      common.send_daily_digest_notifications()
      self.assertEqual(mock_mail.call_count, 1)
Пример #14
0
  def test_enabled_notifications(self, mock_mail):

    with freeze_time("2015-02-01 13:39:20"):
      _, wf = self.wf_generator.generate_workflow(self.quarterly_wf)
      response, wf = self.wf_generator.activate_workflow(wf)
      self.assert200(response)

    with freeze_time("2015-01-29 13:39:20"):
      user = models.Person.query.get(self.user.id)
      _, notif_data = common.get_daily_notifications()
      self.assertIn(user.email, notif_data)

      self.object_generator.generate_notification_setting(
          self.user.id, "Email_Digest", True)

      user = models.Person.query.get(self.user.id)
      _, notif_data = common.get_daily_notifications()
      self.assertIn(user.email, notif_data)
  def test_common_attr_change(self):
    """Test notification when common attribute value is changed"""
    response = self.api.put(self.assessment, {"test_plan": "steps"})
    self.assert200(response)

    notifs, notif_data = common.get_daily_notifications()
    updated = notif_data["*****@*****.**"]["assessment_updated"]
    self.assertEqual(len(notifs), 1)
    self.assertEqual(updated[self.assessment.id]["updated_fields"],
                     ["ASSESSMENT PROCEDURE"])
Пример #16
0
  def test_end_cycle(self, mock_mail):
    """Manually ending cycle should stop all notifications for that cycle."""

    with freeze_time("2015-05-01"):
      _, workflow = self.wf_generator.generate_workflow(
          self.one_time_workflow_1)
      _, cycle = self.wf_generator.generate_cycle(workflow)
      self.wf_generator.activate_workflow(workflow)

    with freeze_time("2015-05-03"):
      _, notif_data = common.get_daily_notifications()
      cycle = Cycle.query.get(cycle.id)
      user = Person.query.get(self.user.id)
      self.assertIn(user.email, notif_data)
      self.wf_generator.modify_object(cycle, data={"is_current": False})
      cycle = Cycle.query.get(cycle.id)
      self.assertFalse(cycle.is_current)

      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(user.email, notif_data)
Пример #17
0
  def test_delete_activated_workflow(self, mock_mail):

    with freeze_time("2015-02-01 13:39:20"):
      _, workflow = self.wf_generator.generate_workflow(self.quarterly_wf_1)
      response, workflow = self.wf_generator.activate_workflow(workflow)

      self.assert200(response)

      user = Person.query.get(self.user.id)

    with freeze_time("2015-01-01 13:39:20"):
      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(user.email, notif_data)

    with freeze_time("2015-01-29 13:39:20"):
      _, notif_data = common.get_daily_notifications()
      self.assertIn(user.email, notif_data)
      self.assertIn("cycle_starts_in", notif_data[user.email])

      workflow = Workflow.query.get(workflow.id)
      # After workflow deletion its notifications object_ids updated to 0
      # value, this is the error, them should be deleted
      # so this query checks existence of notifications with object_id
      # equal to workflow id or 0 id before and
      # after deletion workflow instance
      exists_qs = db.session.query(
          Notification.query.filter(
              Notification.object_type == workflow.__class__.__name__,
              Notification.object_id.in_((workflow.id, 0))
          ).exists()
      )
      self.assertTrue(exists_qs.one()[0])
      response = self.wf_generator.api.delete(workflow)
      self.assert200(response)

      self.assertFalse(exists_qs.one()[0])

      _, notif_data = common.get_daily_notifications()
      user = Person.query.get(self.user.id)

      self.assertNotIn(user.email, notif_data)
Пример #18
0
  def test_manual_generate_cycle(self, mock_mail):

    with freeze_time("2015-04-01"):
      _, wf = self.wf_generator.generate_workflow(self.monthly_workflow_1)
      self.wf_generator.activate_workflow(wf)

      person_1 = Person.query.get(self.person_1.id)

    with freeze_time("2015-04-03"):
      _, notif_data = common.get_daily_notifications()

    with freeze_time("2015-04-03"):
      _, cycle = self.wf_generator.generate_cycle(wf)
      _, notif_data = common.get_daily_notifications()
      person_1 = Person.query.get(self.person_1.id)
      self.assertIn("cycle_started", notif_data[person_1.email])

    with freeze_time("2015-05-03"):  # two days befor due date
      _, notif_data = common.get_daily_notifications()
      person_1 = Person.query.get(self.person_1.id)
      self.assertIn(person_1.email, notif_data)
Пример #19
0
  def test_cycle_starts_in_less_than_X_days(self):

    with freeze_time("2015-02-01"):
      _, wf = self.generator.generate_workflow(self.quarterly_wf_1)
      response, wf = self.generator.activate_workflow(wf)

      self.assert200(response)

      assignee = Person.query.get(self.assignee.id)

    with freeze_time("2015-01-01"):
      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(assignee.email, notif_data)

    with freeze_time("2015-01-29"):
      _, notif_data = common.get_daily_notifications()
      self.assertIn(assignee.email, notif_data)

    with freeze_time("2015-02-01"):
      _, notif_data = common.get_daily_notifications()
      self.assertIn(assignee.email, notif_data)
Пример #20
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_overdue_notifications_when_task_due_date_is_changed(self, _):
    """Overdue notifications should adjust to task due date changes."""
    Workflow.query.delete()
    models.Notification.query.delete()
    db.session.commit()

    filename = join(self.CSV_DIR, "workflow_small_sheet.csv")
    response = self.import_file(filename)
    self._check_csv_response(response, expected_messages={})

    workflow = Workflow.query.one()
    self.wf_generator.generate_cycle(workflow)
    response, workflow = self.wf_generator.activate_workflow(workflow)

    user = models.Person.query.filter(
        models.Person.email == '*****@*****.**').one()

    with freeze_time("2015-01-01 00:00:00"):  # before all tasks' due dates
      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user.email, {})
      self.assertNotIn("task_overdue", user_notifs)

      # now modify task's due date and check if overdue notification appears
      task = CycleTaskGroupObjectTask.query.filter(
          CycleTaskGroupObjectTask.title == "task for wf-2").one()
      task_id, task_code = task.id, task.slug

      response = self.import_data(OrderedDict((
          ("object_type", "CycleTask"),
          ("Code*", task_code),
          ("Start Date", "12/15/2014"),
          ("Due Date", "12/31/2014"),
      )))
      self._check_csv_response(response, expected_messages={})

      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user.email, {})
      self.assertIn("task_overdue", user_notifs)
      self.assertEqual(len(user_notifs["task_overdue"]), 1)
      self.assertIn(task_id, user_notifs["task_overdue"])
  def test_single_task_declined(self, mock_mail):
    """
    test moving the end date to the future, befor due_in and due_today
    notifications have been sent
    """

    with freeze_time("2015-05-01"):
      _, workflow = self.wf_generator.generate_workflow(
          self.one_time_workflow_1)

      _, cycle = self.wf_generator.generate_cycle(workflow)
      self.wf_generator.activate_workflow(workflow)

    with freeze_time("2015-05-02"):
      common.send_daily_digest_notifications()

      cycle = Cycle.query.get(cycle.id)
      task1 = CycleTaskGroupObjectTask.query.get(
          cycle.cycle_task_group_object_tasks[0].id)

      self.task_change_status(task1, "Finished")

      _, notif_data = common.get_daily_notifications()
      self.assertEqual(notif_data, {})

    with freeze_time("2015-05-02"):
      common.send_daily_digest_notifications()

      cycle = Cycle.query.get(cycle.id)
      task1 = CycleTaskGroupObjectTask.query.get(
          cycle.cycle_task_group_object_tasks[0].id)

      self.task_change_status(task1, "Declined")

      user = Person.query.get(self.user.id)
      _, notif_data = common.get_daily_notifications()

      self.assertIn(user.email, notif_data)
      self.assertIn("task_declined", notif_data[user.email])
  def test_multiply_updates(self):
    """Test notification for multiply updates"""
    response = self.api.put(self.assessment, {"test_plan": "steps"})
    self.assert200(response)

    response = self.api.put(self.assessment, {"title": "new title"})
    self.assert200(response)

    notifs, notif_data = common.get_daily_notifications()
    updated = notif_data["*****@*****.**"]["assessment_updated"]
    self.assertEqual(len(notifs), 1)
    self.assertEqual(sorted(updated[self.assessment.id]["updated_fields"]),
                     ["ASSESSMENT PROCEDURE", "TITLE"])
  def test_stop_sending_overdue_notification_if_task_gets_deleted(self,
                                                                  is_vf_needed,
                                                                  _):
    """Overdue notifications should not be sent for deleted tasks."""
    with freeze_time("2017-05-15 14:25:36"):
      tmp = self.one_time_workflow.copy()
      tmp['is_verification_needed'] = is_vf_needed
      _, workflow = self.wf_generator.generate_workflow(tmp)
      self.wf_generator.generate_cycle(workflow)
      response, workflow = self.wf_generator.activate_workflow(workflow)
      self.assert200(response)

    tasks = workflow.cycles[0].cycle_task_group_object_tasks
    task1, task2 = tasks

    user = models.Person.query.get(self.user.id)
    user_email = user.email

    with freeze_time("2017-10-16 08:09:10"):  # long after both task due dates
      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user_email, {})
      self.assertIn("task_overdue", user_notifs)
      self.assertEqual(len(user_notifs["task_overdue"]), 2)

      db.session.delete(task2)
      db.session.commit()

      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user_email, {})
      self.assertIn("task_overdue", user_notifs)
      self.assertEqual(len(user_notifs["task_overdue"]), 1)

      db.session.delete(task1)
      db.session.commit()

      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user.email, {})
      self.assertNotIn("task_overdue", user_notifs)
Пример #25
0
    def test_adjust_overdue_notifications_on_task_due_date_change(
            self, is_vf_needed, _):
        """Sending overdue notifications should adjust to task due date changes."""
        with freeze_time("2017-05-15 14:25:36"):
            tmp = self.one_time_workflow.copy()
            tmp['is_verification_needed'] = is_vf_needed
            _, workflow = self.wf_generator.generate_workflow(tmp)
            self.wf_generator.generate_cycle(workflow)
            response, workflow = self.wf_generator.activate_workflow(workflow)
            self.assert200(response)

            tasks = workflow.cycles[0].cycle_task_group_object_tasks
            task1, task2 = tasks
            self.wf_generator.modify_object(task2,
                                            {"end_date": date(2099, 12, 31)})

            user = models.Person.query.get(self.user.id)

        with freeze_time("2017-05-16 08:09:10"):  # a day after task1 due date
            _, notif_data = common.get_daily_notifications()
            user_notifs = notif_data.get(user.email, {})
            self.assertIn("task_overdue", user_notifs)
            self.assertEqual(len(user_notifs["task_overdue"]), 1)

            # change task1 due date, there should be no overdue notification anymore
            self.wf_generator.modify_object(task1,
                                            {"end_date": date(2017, 5, 16)})
            _, notif_data = common.get_daily_notifications()
            user_notifs = notif_data.get(user.email, {})
            self.assertNotIn("task_overdue", user_notifs)

            # change task1 due date to the past there should a notification again
            self.wf_generator.modify_object(task1,
                                            {"end_date": date(2017, 5, 14)})
            _, notif_data = common.get_daily_notifications()
            user_notifs = notif_data.get(user.email, {})
            self.assertIn("task_overdue", user_notifs)
            self.assertEqual(len(user_notifs["task_overdue"]), 1)
    def test_stop_sending_overdue_notification_if_task_gets_deleted(
            self, is_vf_needed, _):
        """Overdue notifications should not be sent for deleted tasks."""
        with freeze_time("2017-05-15 14:25:36"):
            tmp = self.one_time_workflow.copy()
            tmp['is_verification_needed'] = is_vf_needed
            _, workflow = self.wf_generator.generate_workflow(tmp)
            self.wf_generator.generate_cycle(workflow)
            response, workflow = self.wf_generator.activate_workflow(workflow)
            self.assert200(response)

        tasks = workflow.cycles[0].cycle_task_group_object_tasks
        task1, task2 = tasks

        user = models.Person.query.get(self.user.id)
        user_email = user.email

        with freeze_time(
                "2017-10-16 08:09:10"):  # long after both task due dates
            _, notif_data = common.get_daily_notifications()
            user_notifs = notif_data.get(user_email, {})
            self.assertIn("task_overdue", user_notifs)
            self.assertEqual(len(user_notifs["task_overdue"]), 2)

            db.session.delete(task2)
            db.session.commit()

            _, notif_data = common.get_daily_notifications()
            user_notifs = notif_data.get(user_email, {})
            self.assertIn("task_overdue", user_notifs)
            self.assertEqual(len(user_notifs["task_overdue"]), 1)

            db.session.delete(task1)
            db.session.commit()

            _, notif_data = common.get_daily_notifications()
            user_notifs = notif_data.get(user.email, {})
            self.assertNotIn("task_overdue", user_notifs)
Пример #27
0
    def test_marking_sent_notifications(self, mail_mock):
        mail_mock.return_value = True

        with freeze_time("2015-02-01"):
            _, wf = self.generator.generate_workflow(self.quarterly_wf_1)
            response, wf = self.generator.activate_workflow(wf)

            self.assert200(response)

            assignee = Person.query.get(self.assignee.id)

        with freeze_time("2015-01-01"):
            _, notif_data = common.get_daily_notifications()
            self.assertNotIn(assignee.email, notif_data)

        with freeze_time("2015-01-29"):
            common.send_daily_digest_notifications()
            _, notif_data = common.get_daily_notifications()
            self.assertNotIn(assignee.email, notif_data)

        with freeze_time("2015-02-01"):
            _, notif_data = common.get_daily_notifications()
            self.assertNotIn(assignee.email, notif_data)
Пример #28
0
    def test_grouping_comments(self, _):
        """Test that comments are grouped by parent object in daily digest data."""

        factories.AuditFactory(slug="Audit")
        self.import_file("assessment_template_no_warnings.csv")
        self.import_file("assessment_with_templates.csv")
        asmt1 = Assessment.query.filter_by(slug="A 1").first()
        asmt4 = Assessment.query.filter_by(slug="A 4").first()
        asmt6 = Assessment.query.filter_by(slug="A 6").first()

        asmt_ids = (asmt1.id, asmt4.id, asmt6.id)

        self.generator.generate_comment(asmt1,
                                        "Verifiers",
                                        "comment X on asmt " + str(asmt1.id),
                                        send_notification="true")
        self.generator.generate_comment(asmt6,
                                        "Verifiers",
                                        "comment A on asmt " + str(asmt6.id),
                                        send_notification="true")
        self.generator.generate_comment(asmt4,
                                        "Verifiers",
                                        "comment FOO on asmt " + str(asmt4.id),
                                        send_notification="true")
        self.generator.generate_comment(asmt4,
                                        "Verifiers",
                                        "comment BAR on asmt " + str(asmt4.id),
                                        send_notification="true")
        self.generator.generate_comment(asmt1,
                                        "Verifiers",
                                        "comment Y on asmt " + str(asmt1.id),
                                        send_notification="true")

        _, notif_data = common.get_daily_notifications()

        assignee_notifs = notif_data.get("*****@*****.**", {})
        common.sort_comments(assignee_notifs)
        comment_notifs = assignee_notifs.get("comment_created", {})
        self.assertEqual(len(comment_notifs), 3)  # for 3 different Assessments

        # for each group of comment notifications, check that it contains comments
        # for that particular Assessment
        for parent_obj_key, comments_info in comment_notifs.iteritems():
            self.assertIn(parent_obj_key.id, asmt_ids)
            for comment in comments_info:
                self.assertEqual(comment["parent_id"], parent_obj_key.id)
                self.assertEqual(comment["parent_type"], "Assessment")
                expected_suffix = "asmt " + str(parent_obj_key.id)
                self.assertTrue(
                    comment["description"].endswith(expected_suffix))
Пример #29
0
  def test_marking_sent_notifications(self, mail_mock):
    mail_mock.return_value = True

    with freeze_time("2015-02-01"):
      _, wf = self.generator.generate_workflow(self.quarterly_wf_1)
      response, wf = self.generator.activate_workflow(wf)

      self.assert200(response)

      assignee = Person.query.get(self.assignee.id)

    with freeze_time("2015-01-01"):
      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(assignee.email, notif_data)

    with freeze_time("2015-01-29"):
      common.send_daily_digest_notifications()
      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(assignee.email, notif_data)

    with freeze_time("2015-02-01"):
      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(assignee.email, notif_data)
    def test_single_task_accepted(self, mock_mail):
        """
    test moving the end date to the future, befor due_in and due_today
    notifications have been sent
    """

        with freeze_time("2015-05-01"):
            _, workflow = self.wf_generator.generate_workflow(
                self.one_time_workflow_1)

            _, cycle = self.wf_generator.generate_cycle(workflow)
            self.wf_generator.activate_workflow(workflow)

        with freeze_time("2015-05-02"):
            common.send_daily_digest_notifications()

            cycle = Cycle.query.get(cycle.id)
            task1 = CycleTaskGroupObjectTask.query.get(
                cycle.cycle_task_group_object_tasks[0].id)

            self.task_change_status(task1, "Finished")

            _, notif_data = common.get_daily_notifications()
            self.assertEqual(notif_data, {})

        with freeze_time("2015-05-03"):
            cycle = Cycle.query.get(cycle.id)
            task1 = CycleTaskGroupObjectTask.query.get(
                cycle.cycle_task_group_object_tasks[0].id)

            self.task_change_status(task1)

            user = Person.query.get(self.user.id)
            _, notif_data = common.get_daily_notifications()
            self.assertNotIn(user.email, notif_data)
            self.assertIn("all_tasks_completed",
                          notif_data["*****@*****.**"])
Пример #31
0
    def test_adjust_overdue_notifications_on_task_status_change(self, _):
        """Sending overdue notifications should take task status into account."""
        with freeze_time("2017-05-15 14:25:36"):
            _, workflow = self.wf_generator.generate_workflow(
                self.one_time_workflow)
            self.wf_generator.generate_cycle(workflow)
            response, workflow = self.wf_generator.activate_workflow(workflow)
            self.assert200(response)

        tasks = workflow.cycles[0].cycle_task_group_object_tasks
        task1, task2 = tasks
        self.wf_generator.modify_object(task2,
                                        {"end_date": date(2099, 12, 31)})

        user = models.Person.query.get(self.user.id)
        user_email = user.email

        with freeze_time("2017-05-16 08:09:10"):  # a day after task1 due date
            for state in CycleTaskGroupObjectTask.ACTIVE_STATES:
                # clear all notifications before before changing the task status
                models.Notification.query.delete()
                _, notif_data = common.get_daily_notifications()
                self.assertEqual(notif_data, {})

                self.wf_generator.modify_object(task1, {"status": state})

                _, notif_data = common.get_daily_notifications()
                user_notifs = notif_data.get(user_email, {})
                self.assertIn("task_overdue", user_notifs)
                self.assertEqual(len(user_notifs["task_overdue"]), 1)

            # WITHOUT clearing the overdue notifications, move the task to "verified"
            # state, and the overdue notification should disappear.
            self.wf_generator.modify_object(task1, {"status": "Verified"})
            _, notif_data = common.get_daily_notifications()
            user_notifs = notif_data.get(user_email, {})
            self.assertNotIn("task_overdue", user_notifs)
Пример #32
0
  def test_single_task_accepted(self, mock_mail):
    """Test moving the end date to the future on accepted task.

    It is done before due_in and due_today notifications have been sent.
    """

    with freeze_time("2015-05-01"):
      _, workflow = self.wf_generator.generate_workflow(
          self.one_time_workflow_1)

      _, cycle = self.wf_generator.generate_cycle(workflow)
      self.wf_generator.activate_workflow(workflow)

    with freeze_time("2015-05-02"):
      common.send_daily_digest_notifications()

      cycle = Cycle.query.get(cycle.id)
      task1 = CycleTaskGroupObjectTask.query.get(
          cycle.cycle_task_group_object_tasks[0].id)

      self.task_change_status(task1, "Finished")

      _, notif_data = common.get_daily_notifications()
      self.assertEqual(notif_data, {})

    with freeze_time("2015-05-03 13:20:34"):
      cycle = Cycle.query.get(cycle.id)
      task1 = CycleTaskGroupObjectTask.query.get(
          cycle.cycle_task_group_object_tasks[0].id)

      self.task_change_status(task1)

      generate_cycle_tasks_notifs()
      user = Person.query.get(self.user.id)
      _, notif_data = common.get_daily_notifications()
      self.assertNotIn(user.email, notif_data)
      self.assertIn("all_tasks_completed", notif_data["*****@*****.**"])
Пример #33
0
    def test_auto_generate_cycle(self, mock_mail):

        with freeze_time("2015-04-01"):
            _, wf = self.wf_generator.generate_workflow(
                self.monthly_workflow_1)
            self.wf_generator.activate_workflow(wf)

            person_1 = Person.query.get(self.person_1.id)

        with freeze_time("2015-04-02"):
            _, notif_data = common.get_daily_notifications()
            self.assertIn(person_1.email, notif_data)
            self.assertIn("cycle_starts_in", notif_data[person_1.email])

        with freeze_time("2015-04-02"):
            self.api.tc.get("nightly_cron_endpoint")
            _, notif_data = common.get_daily_notifications()
            self.assertNotIn(person_1.email, notif_data)

        with freeze_time("2015-04-02"):
            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()

        with freeze_time("2015-04-15"):  # one day befor due date
            _, notif_data = common.get_daily_notifications()
            person_1 = Person.query.get(self.person_1.id)
            self.assertIn(person_1.email, notif_data)

        with freeze_time("2015-04-25"):  # due date
            _, notif_data = common.get_daily_notifications()
            person_1 = Person.query.get(self.person_1.id)
            self.assertIn(person_1.email, notif_data)
Пример #34
0
  def test_models_comments(self, obj_factory, _):
    """Test setting notification entries for model comments.

    Check if the correct notification entries are created when a comment gets
    posted.
    """
    if obj_factory in self.SCOPING_OBJECT_FACTORIES:
      recipient_types = ["Admin", "Primary Contacts", "Secondary Contacts",
                         "Product Managers", "Technical / Program Managers",
                         "Technical Leads", "System Owners", "Legal Counsels"]
    else:
      recipient_types = ["Admin", "Primary Contacts", "Secondary Contacts"]
    person = all_models.Person.query.first()
    person_email = person.email

    with factories.single_commit():
      obj = obj_factory(
          recipients=",".join(recipient_types),
          send_by_default=False,
      )
      ac_roles = get_custom_roles_for(obj.type)
      for acr_id, acr_name in ac_roles.items():
        if acr_name in recipient_types:
          factories.AccessControlListFactory(
              ac_role_id=acr_id, object=obj, person=person
          )

    self.generator.generate_comment(
        obj, "", "some comment", send_notification="true")

    notifications, notif_data = common.get_daily_notifications()
    self.assertEqual(len(notifications), 1,
                     "Missing comment notification entry.")

    recip_notifs = notif_data.get(person_email, {})
    comment_notifs = recip_notifs.get("comment_created", {})
    self.assertEqual(len(comment_notifs), 1)

    # Check if correct revisions count is created
    revisions = Revision.query.filter(
        Revision.resource_type == 'Notification',
        Revision.resource_id.in_([n.id for n in notifications])
    )
    self.assertEqual(revisions.count(), 1)

    self.client.get("/_notifications/send_daily_digest")
    notifications = self._get_notifications(notif_type="comment_created").all()
    self.assertEqual(len(notifications), 0,
                     "Found a comment notification that was not sent.")
Пример #35
0
    def test_one_time_wf_activate(self):
        def get_person(person_id):
            return db.session.query(Person).filter(
                Person.id == person_id).one()

        with freeze_time("2015-04-10"):
            _, wf = self.wf_generator.generate_workflow(
                self.one_time_workflow_1)

            _, cycle = self.wf_generator.generate_cycle(wf)
            self.wf_generator.activate_workflow(wf)

            person_1 = get_person(self.random_people[0].id)

        with freeze_time("2015-04-11"):
            _, notif_data = common.get_daily_notifications()
            self.assertIn("cycle_started", notif_data[person_1.email])
            self.assertIn(cycle.id,
                          notif_data[person_1.email]["cycle_started"])
            self.assertIn(
                "my_tasks",
                notif_data[person_1.email]["cycle_started"][cycle.id])

        with freeze_time("2015-05-03"):  # two days befor due date
            _, notif_data = common.get_daily_notifications()
            self.assertIn(person_1.email, notif_data)
            self.assertNotIn("due_in", notif_data[person_1.email])
            self.assertNotIn("due_today", notif_data[person_1.email])

        with freeze_time("2015-05-04"):  # one day befor due date
            _, notif_data = common.get_daily_notifications()
            self.assertEqual(len(notif_data[person_1.email]["due_in"]), 1)

        with freeze_time("2015-05-05"):  # due date
            _, notif_data = common.get_daily_notifications()
            self.assertEqual(len(notif_data[person_1.email]["due_today"]), 1)
  def test_custom_attr_change(self):
    """Test notification when custom attribute value is changed"""
    custom_attribute_values = [{
        "custom_attribute_id": self.cad1.id,
        "attribute_value": "test value",
    }]
    response = self.api.put(self.assessment, {
        "custom_attribute_values": custom_attribute_values
    })
    self.assert200(response)

    notifs, notif_data = common.get_daily_notifications()
    updated = notif_data["*****@*****.**"]["assessment_updated"]
    self.assertEqual(len(notifs), 1)
    self.assertEqual(updated[self.assessment.id]["updated_fields"], ["CA1"])
Пример #37
0
    def test_delete_activated_workflow(self, mock_mail):

        with freeze_time("2015-02-01 13:39:20"):
            _, workflow = self.wf_generator.generate_workflow(
                self.quarterly_wf_1)
            response, workflow = self.wf_generator.activate_workflow(workflow)

            self.assert200(response)

            user = Person.query.get(self.user.id)

        with freeze_time("2015-01-01 13:39:20"):
            _, notif_data = common.get_daily_notifications()
            self.assertNotIn(user.email, notif_data)

        with freeze_time("2015-01-29 13:39:20"):
            _, notif_data = common.get_daily_notifications()
            self.assertIn(user.email, notif_data)
            self.assertIn("cycle_starts_in", notif_data[user.email])

            workflow = Workflow.query.get(workflow.id)

            exists_qs = db.session.query(
                Notification.query.filter(
                    Notification.object_id == workflow.id,
                    Notification.object_type ==
                    workflow.__class__.__name__).exists())
            self.assertTrue(exists_qs.one()[0])
            response = self.wf_generator.api.delete(workflow)
            self.assert200(response)
            self.assertFalse(exists_qs.one()[0])

            _, notif_data = common.get_daily_notifications()
            user = Person.query.get(self.user.id)

            self.assertNotIn(user.email, notif_data)
  def test_adjust_overdue_notifications_on_task_due_date_change(self,
                                                                is_vf_needed,
                                                                _):
    """Sending overdue notifications should adjust to task due date changes."""
    with freeze_time("2017-05-15 14:25:36"):
      tmp = self.one_time_workflow.copy()
      tmp['is_verification_needed'] = is_vf_needed
      _, workflow = self.wf_generator.generate_workflow(tmp)
      self.wf_generator.generate_cycle(workflow)
      response, workflow = self.wf_generator.activate_workflow(workflow)
      self.assert200(response)

      tasks = workflow.cycles[0].cycle_task_group_object_tasks
      task1, task2 = tasks
      self.wf_generator.modify_object(task2, {"end_date": date(2099, 12, 31)})

      user = models.Person.query.get(self.user.id)

    with freeze_time("2017-05-16 08:09:10"):  # a day after task1 due date
      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user.email, {})
      self.assertIn("task_overdue", user_notifs)
      self.assertEqual(len(user_notifs["task_overdue"]), 1)

      # change task1 due date, there should be no overdue notification anymore
      self.wf_generator.modify_object(task1, {"end_date": date(2017, 5, 16)})
      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user.email, {})
      self.assertNotIn("task_overdue", user_notifs)

      # change task1 due date to the past there should a notification again
      self.wf_generator.modify_object(task1, {"end_date": date(2017, 5, 14)})
      _, notif_data = common.get_daily_notifications()
      user_notifs = notif_data.get(user.email, {})
      self.assertIn("task_overdue", user_notifs)
      self.assertEqual(len(user_notifs["task_overdue"]), 1)
  def test_custom_attr_change(self):
    """Test notification when custom attribute value is changed"""
    custom_attribute_values = [{
        "custom_attribute_id": self.cad1.id,
        "attribute_value": "test value",
    }]
    response = self.api.put(self.assessment, {
        "custom_attribute_values": custom_attribute_values
    })
    self.assert200(response)

    notifs, notif_data = common.get_daily_notifications()
    updated = notif_data["*****@*****.**"]["assessment_updated"]
    self.assertEqual(len(notifs), 1)
    self.assertEqual(updated[self.assessment.id]["updated_fields"], ["CA1"])
Пример #40
0
    def test_multiply_updates(self):
        """Test notification for multiply updates"""
        response = self.api.put(self.assessment, {"test_plan": "steps"})
        self.assert200(response)

        response = self.api.put(self.assessment, {"title": "new title"})
        self.assert200(response)

        notifs, notif_data = common.get_daily_notifications()
        updated = notif_data["*****@*****.**"]["assessment_updated"]
        self.assertEqual(len(notifs), 1)
        self.assertEqual(updated[self.assessment.id]["updated_data"]["TITLE"],
                         ("new title", "Assessment1"))
        self.assertEqual(
            updated[self.assessment.id]["updated_data"]
            ["ASSESSMENT PROCEDURE"], ("steps", ""))
Пример #41
0
  def test_get_daily_notification_huge_data(self):
    """Test that we do not loose any notifications during merging chunks"""
    notif_list = mock.MagicMock(return_value=None)

    content = [(notif_list, {"*****@*****.**": {"notif": {"id": 1}}}),
               (notif_list, {"*****@*****.**": {"notif 2": {"id": 1}}}),
               (notif_list, {"*****@*****.**": {"notif": {"id": 1}}})]

    expected_data = {"*****@*****.**": {"notif": {"id": 1}},
                     "*****@*****.**": {"notif": {"id": 1},
                                          "notif 2": {"id": 1}}}

    with mock.patch("ggrc.notifications.common.generate_daily_notifications",
                    return_value=content):
      _, notif_data = common.get_daily_notifications()
      self.assertEqual(expected_data, notif_data)
Пример #42
0
    def test_description_custom_change(self):
        """Test notification updated data when custom attribute value is changed"""
        response = self.api.put(self.assessment, {
            "title": "test_title",
            "description": "test_description"
        })
        self.assert200(response)

        notifs, notif_data = common.get_daily_notifications()
        updated = notif_data["*****@*****.**"]["assessment_updated"]
        self.assertEqual(len(notifs), 1)
        self.assertEqual(updated[self.assessment.id]["updated_data"]["TITLE"],
                         ("test_title", "Assessment1"))
        self.assertEqual(
            updated[self.assessment.id]["updated_data"]["DESCRIPTION"],
            ("test_description", ""))
    def test_no_date_change(self, mock_mail):
        """Test a basic case with no moving end date"""
        with freeze_time("2015-04-10 03:21:34"):
            _, workflow = self.wf_generator.generate_workflow(
                self.one_time_workflow_1)

            _, cycle = self.wf_generator.generate_cycle(workflow)
            self.wf_generator.activate_workflow(workflow)

        assignee = self.user
        task_assignees = [assignee, self.secondary_assignee]
        with freeze_time("2015-04-11 03:21:34"):
            _, notif_data = common.get_daily_notifications()

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

        with freeze_time("2015-05-02 03:21:34"):
            _, notif_data = common.get_daily_notifications()
            self.assertIn(assignee.email, notif_data)

            # cycle started notifs available only for contact
            self.assertIn("cycle_started", notif_data[assignee.email])
            for user in task_assignees:
                self.assertNotIn("due_in", notif_data[user.email])
                self.assertNotIn("due_today", notif_data[user.email])

        with freeze_time("2015-05-02 03:21:34"):
            common.send_daily_digest_notifications()
            _, notif_data = common.get_daily_notifications()
            self.assertEqual(notif_data, {})

            # one email to admin, one to assigne and one to secondary assignee
            self.assertEqual(mock_mail.call_count, 3)

        with freeze_time("2015-05-04 03:21:34"):  # one day before due date
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                self.assertIn(user.email, notif_data)
                self.assertIn("due_in", notif_data[user.email])
                self.assertEqual(len(notif_data[user.email]["due_in"]), 2)

        with freeze_time("2015-05-04 03:21:34"):  # one day before due date
            common.send_daily_digest_notifications()
            _, notif_data = common.get_daily_notifications()
            self.assertEqual(notif_data, {})

            # one email to admin and two each to assigne and secondary assignee
            self.assertEqual(mock_mail.call_count, 5)

        with freeze_time("2015-05-05 03:21:34"):  # due date
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                self.assertIn("due_today", notif_data[user.email])
                self.assertEqual(len(notif_data[user.email]["due_today"]), 2)
Пример #44
0
 def test_labels_change(self):
     """Test notification updated data when labels are changed"""
     label_new = factories.LabelFactory(name="test_label",
                                        object_type='Assessment')
     response = self.api.put(
         self.assessment,
         {'labels': [{
             "name": label_new.name,
             "id": label_new.id
         }]})
     self.assert200(response)
     notifs, notif_data = common.get_daily_notifications()
     updated = notif_data["*****@*****.**"]["assessment_updated"]
     self.assertEqual(len(notifs), 1)
     self.assertEqual(updated[self.assessment.id]["updated_data"]["LABELS"],
                      ("test_label", ""))
Пример #45
0
    def test_models_comments(self, obj_factory, _):
        """Test setting notification entries for model comments.

    Check if the correct notification entries are created when a comment gets
    posted.
    """
        recipient_types = ["Admin", "Primary Contacts", "Secondary Contacts"]
        person = all_models.Person.query.first()
        person_email = person.email

        with factories.single_commit():
            obj = obj_factory(
                recipients=",".join(recipient_types),
                send_by_default=False,
            )
            ac_roles = get_custom_roles_for(obj.type)
            for acr_id, acr_name in ac_roles.items():
                if acr_name in recipient_types:
                    factories.AccessControlListFactory(ac_role_id=acr_id,
                                                       object=obj,
                                                       person=person)

        self.generator.generate_comment(obj,
                                        "",
                                        "some comment",
                                        send_notification="true")

        notifications, notif_data = common.get_daily_notifications()
        self.assertEqual(len(notifications), 1,
                         "Missing comment notification entry.")

        recip_notifs = notif_data.get(person_email, {})
        comment_notifs = recip_notifs.get("comment_created", {})
        self.assertEqual(len(comment_notifs), 1)

        # Check if correct revisions count is created
        revisions = Revision.query.filter(
            Revision.resource_type == 'Notification',
            Revision.resource_id.in_([n.id for n in notifications]))
        self.assertEqual(revisions.count(), 1)

        self.client.get("/_notifications/send_daily_digest")
        notifications = self._get_notifications(
            notif_type="comment_created").all()
        self.assertEqual(len(notifications), 0,
                         "Found a comment notification that was not sent.")
Пример #46
0
    def test_models_comments(self, model, _):
        """Test setting notification entries for model comments.

    Check if the correct notification entries are created when a comment gets
    posted.
    """
        recipient_types = model.VALID_RECIPIENTS
        person = all_models.Person.query.first()
        person_email = person.email

        with factories.single_commit():
            obj = factories.get_model_factory(model.__name__)(
                recipients=",".join(recipient_types),
                send_by_default=False,
            )
            for acl in obj._access_control_list:  # pylint: disable=protected-access
                if acl.ac_role.name in recipient_types:
                    factories.AccessControlPersonFactory(
                        ac_list=acl,
                        person=person,
                    )
        self.generator.generate_comment(obj,
                                        "",
                                        "some comment",
                                        send_notification="true")

        notifications, notif_data = common.get_daily_notifications()
        self.assertEqual(len(notifications), 1,
                         "Missing comment notification entry.")

        recip_notifs = notif_data.get(person_email, {})
        comment_notifs = recip_notifs.get("comment_created", {})
        self.assertEqual(len(comment_notifs), 1)

        # Check if correct revisions count is created
        revisions = Revision.query.filter(
            Revision.resource_type == 'Notification',
            Revision.resource_id.in_([n.id for n in notifications]))
        self.assertEqual(revisions.count(), 1)

        self.client.get("/_notifications/send_daily_digest")
        notifications = self._get_notifications(
            notif_type="comment_created").all()
        self.assertEqual(len(notifications), 0,
                         "Found a comment notification that was not sent.")
    def test_creating_obsolete_notifications(self, fake_now, expected_overdue,
                                             expected_due_today,
                                             expected_due_in, _):
        """Notifications already obsolete on creation date should not be created.
    """
        # pylint: disable=invalid-name
        with freeze_time("2017-06-12 09:39:32"):
            tmp = self.one_time_workflow.copy()
            _, workflow = self.wf_generator.generate_workflow(tmp)
            self.wf_generator.generate_cycle(workflow)
            response, workflow = self.wf_generator.activate_workflow(workflow)
            self.assert200(response)

        task_assignees = [self.user, self.secondary_assignee]
        with freeze_time(fake_now):
            # mark all yeasterday notifications as sent
            all_models.Notification.query.filter(
                sa.func.DATE(all_models.Notification.send_on) < date.today()
            ).update(
                {
                    all_models.Notification.sent_at:
                    datetime.now() - timedelta(1)
                },
                synchronize_session="fetch")

            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                user_notifs = notif_data.get(user.email, {})

                actual_overdue = [
                    n['title']
                    for n in user_notifs.get("task_overdue", {}).itervalues()
                ]
                actual_overdue.sort()
                self.assertEqual(actual_overdue, expected_overdue)

                self.assertEqual([
                    n['title']
                    for n in user_notifs.get("due_today", {}).itervalues()
                ], expected_due_today)

                self.assertEqual([
                    n['title']
                    for n in user_notifs.get("due_in", {}).itervalues()
                ], expected_due_in)
Пример #48
0
  def test_grouping_comments(self, _):
    """Test that comments are grouped by parent object in daily digest data."""

    factories.AuditFactory(slug="Audit")
    self.import_file("assessment_template_no_warnings.csv")
    self.import_file("assessment_with_templates.csv")
    asmt1 = Assessment.query.filter_by(slug="A 1").first()
    asmt4 = Assessment.query.filter_by(slug="A 4").first()
    asmt6 = Assessment.query.filter_by(slug="A 6").first()

    asmt_ids = (asmt1.id, asmt4.id, asmt6.id)

    self.generator.generate_comment(
        asmt1, "Verifiers", "comment X on asmt " + str(asmt1.id),
        send_notification="true")
    self.generator.generate_comment(
        asmt6, "Verifiers", "comment A on asmt " + str(asmt6.id),
        send_notification="true")
    self.generator.generate_comment(
        asmt4, "Verifiers", "comment FOO on asmt " + str(asmt4.id),
        send_notification="true")
    self.generator.generate_comment(
        asmt4, "Verifiers", "comment BAR on asmt " + str(asmt4.id),
        send_notification="true")
    self.generator.generate_comment(
        asmt1, "Verifiers", "comment Y on asmt " + str(asmt1.id),
        send_notification="true")

    _, notif_data = common.get_daily_notifications()

    assignee_notifs = notif_data.get("*****@*****.**", {})
    common.sort_comments(assignee_notifs)
    comment_notifs = assignee_notifs.get("comment_created", {})
    self.assertEqual(len(comment_notifs), 3)  # for 3 different Assessments

    # for each group of comment notifications, check that it contains comments
    # for that particular Assessment
    for parent_obj_key, comments_info in comment_notifs.iteritems():
      self.assertIn(parent_obj_key.id, asmt_ids)
      for comment in comments_info:
        self.assertEqual(comment["parent_id"], parent_obj_key.id)
        self.assertEqual(comment["parent_type"], "Assessment")
        expected_suffix = "asmt " + str(parent_obj_key.id)
        self.assertTrue(comment["description"].endswith(expected_suffix))
  def test_ctgot_comments(self, _):
    """Test setting notification entries for ctgot comments.

    Check if the correct notification entries are created when a comment gets
    posted.
    """
    person = all_models.Person.query.first()
    secondary_assignee = self.create_user_with_role(role="Reader")
    task_assignees_emails = [person.email, secondary_assignee.email]
    recipients = {
        "Task Assignees": person,
        "Task Secondary Assignees": secondary_assignee,
    }
    with factories.single_commit():
      obj = wf_factories.CycleTaskGroupObjectTaskFactory(
          recipients=",".join(recipients),
          send_by_default=False,
      )
      # pylint: disable=protected-access
      for acl in obj._access_control_list:
        if acl.ac_role.name in recipients:
          recipient = recipients.get(acl.ac_role.name)
          if recipient:
            factories.AccessControlPersonFactory(
                ac_list=acl,
                person=recipient,
            )

    self.generator.generate_comment(
        obj, "", "some comment", send_notification="true")

    notifications, notif_data = common.get_daily_notifications()
    for email in task_assignees_emails:
      self.assertEqual(len(notifications), 1,
                       "Missing comment notification entry.")

      recip_notifs = notif_data.get(email, {})
      comment_notifs = recip_notifs.get("comment_created", {})
      self.assertEqual(len(comment_notifs), 1)

    self.client.get("/_notifications/send_daily_digest")
    notifications = self._get_notifications(notif_type="comment_created").all()
    self.assertEqual(len(notifications), 0,
                     "Found a comment notification that was not sent.")
Пример #50
0
    def test_no_date_change(self, mock_mail):
        def get_person(person_id):
            return db.session.query(Person).filter(
                Person.id == person_id).one()

        with freeze_time("2015-04-10 03:21:34"):
            _, workflow = self.wf_generator.generate_workflow(
                self.one_time_workflow_1)

            _, cycle = self.wf_generator.generate_cycle(workflow)
            self.wf_generator.activate_workflow(workflow)

        with freeze_time("2015-04-11 03:21:34"):
            user = get_person(self.user.id)
            _, notif_data = common.get_daily_notifications()
            self.assertIn("cycle_started", notif_data[user.email])

        with freeze_time("2015-05-02 03:21:34"):
            _, notif_data = common.get_daily_notifications()
            self.assertIn(user.email, notif_data)
            self.assertIn("cycle_started", notif_data[user.email])
            self.assertNotIn("due_in", notif_data[user.email])
            self.assertNotIn("due_today", notif_data[user.email])

        with freeze_time("2015-05-02 03:21:34"):
            common.send_daily_digest_notifications()
            _, notif_data = common.get_daily_notifications()
            self.assertEqual(notif_data, {})

            # one email to admin and one to assigne
            self.assertEqual(mock_mail.call_count, 2)

        with freeze_time("2015-05-04 03:21:34"):  # one day before due date
            _, notif_data = common.get_daily_notifications()
            user = get_person(self.user.id)
            self.assertIn(user.email, notif_data)
            self.assertIn("due_in", notif_data[user.email])
            self.assertEqual(len(notif_data[user.email]["due_in"]), 2)

        with freeze_time("2015-05-04 03:21:34"):  # one day before due date
            common.send_daily_digest_notifications()
            _, notif_data = common.get_daily_notifications()
            self.assertEqual(notif_data, {})

            # one email to admin and one to assigne
            self.assertEqual(mock_mail.call_count, 3)

        with freeze_time("2015-05-05 03:21:34"):  # due date
            _, notif_data = common.get_daily_notifications()
            self.assertIn("due_today", notif_data[user.email])
            self.assertEqual(len(notif_data[user.email]["due_today"]), 2)
    def test_access_conrol_list(self):
        """Test notification when access conrol list is changed"""
        response = self.api.put(
            self.assessment, {
                "access_control_list": [{
                    "person": {
                        "id": self.auditor.id,
                        "type": "Person",
                    },
                    "ac_role_id": self.secondary_role_id,
                    "context": None
                }],
            })
        self.assert200(response)

        notifs, notif_data = common.get_daily_notifications()
        updated = notif_data["*****@*****.**"]["assessment_updated"]
        self.assertEqual(len(notifs), 1)
        self.assertEqual(updated[self.assessment.id]["updated_fields"],
                         ["PRIMARY CONTACTS", "SECONDARY CONTACTS"])
    def test_access_conrol_list(self):
        """Test notification when access conrol list is changed"""
        assignee_acr = all_models.AccessControlRole.query.filter_by(
            object_type="Assessment",
            name="Assignees",
        ).first()
        response = self.api.put(
            self.assessment, {
                "access_control_list": [
                    acl_helper.get_acl_json(self.secondary_role_id,
                                            self.auditor.id),
                    acl_helper.get_acl_json(assignee_acr.id, self.auditor.id)
                ],
            })
        self.assert200(response)

        notifs, notif_data = common.get_daily_notifications()
        updated = notif_data["*****@*****.**"]["assessment_updated"]
        self.assertEqual(len(notifs), 1)
        self.assertEqual(updated[self.assessment.id]["updated_fields"],
                         ["PRIMARY CONTACTS", "SECONDARY CONTACTS"])
    def test_creating_overdue_notifications_for_new_tasks(self, _):
        """Overdue notifications should be created for tasks created with imports.
    """
        Workflow.query.delete()
        models.Notification.query.delete()
        db.session.commit()

        filename = join(self.CSV_DIR, "workflow_small_sheet.csv")
        self.import_file(filename)

        workflow = Workflow.query.one()
        self.wf_generator.generate_cycle(workflow)
        response, workflow = self.wf_generator.activate_workflow(workflow)

        user = models.Person.query.filter(
            models.Person.email == '*****@*****.**').one()

        with freeze_time("2020-01-01 00:00:00"):  # afer all tasks' due dates
            _, notif_data = common.get_daily_notifications()
            user_notifs = notif_data.get(user.email, {})
            self.assertIn("task_overdue", user_notifs)
            self.assertEqual(len(user_notifs["task_overdue"]), 4)
Пример #54
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)
    def test_move_end_date_to_today(self, mock_mail):
        def get_person(person_id):
            return db.session.query(Person).filter(
                Person.id == person_id).one()

        with freeze_time("2015-04-10 03:21:34"):
            _, workflow = self.wf_generator.generate_workflow(
                self.one_time_workflow_1)

            _, cycle = self.wf_generator.generate_cycle(workflow)
            self.wf_generator.activate_workflow(workflow)

        with freeze_time("2015-05-02 03:21:34"):
            common.send_daily_digest_notifications()
            _, notif_data = common.get_daily_notifications()
            self.assertEqual(notif_data, {})

            # one email to owner and one to assigne
            self.assertEqual(mock_mail.call_count, 2)

        with freeze_time("2015-05-03 03:21:34"):
            cycle = Cycle.query.get(cycle.id)
            task1 = CycleTaskGroupObjectTask.query.get(
                cycle.cycle_task_group_object_tasks[0].id)
            task2 = CycleTaskGroupObjectTask.query.get(
                cycle.cycle_task_group_object_tasks[1].id)

            self.wf_generator.modify_object(
                task1, data={"end_date": date(2015, 5, 3)})
            self.wf_generator.modify_object(
                task2, data={"end_date": date(2015, 5, 4)})

        with freeze_time("2015-05-03 03:21:34"):  # one day before due date
            user = get_person(self.user.id)
            _, notif_data = common.get_daily_notifications()

            self.assertNotEqual(notif_data, {})
            self.assertIn(user.email, notif_data)
            self.assertIn("due_today", notif_data[user.email])
            self.assertIn("due_in", notif_data[user.email])
            self.assertEqual(len(notif_data[user.email]["due_today"]), 1)

            common.send_daily_digest_notifications()

        with freeze_time("2015-05-04 03:21:34"):  # due date (of task2)
            user = get_person(self.user.id)
            _, notif_data = common.get_daily_notifications()
            self.assertIn(user.email, notif_data)
            self.assertIn("due_today", notif_data[user.email])
            self.assertNotIn("due_in", notif_data[user.email])
            common.send_daily_digest_notifications()

        # check that overdue notifications are sent even on days after the day a
        # task has become due, unlike the "due_today" and "due_in" notifications
        with freeze_time("2015-05-05 03:21:34"):  # 1+ days after due date(s)
            _, notif_data = common.get_daily_notifications()
            self.assertNotEqual(notif_data, {})
            self.assertIn(user.email, notif_data)

            user_notifs = notif_data[user.email]
            self.assertNotIn("due_today", user_notifs)
            self.assertNotIn("due_in", user_notifs)

            self.assertIn("task_overdue", user_notifs)
            self.assertEqual(len(user_notifs["task_overdue"]), 2)
Пример #56
0
  def test_move_end_date_to_future(self, mock_mail):
    """
    test moving the end date to the future, befor due_in and due_today
    notifications have been sent
    """
    def get_person(person_id):
      return db.session.query(Person).filter(Person.id == person_id).one()

    with freeze_time("2015-04-10 03:21:34"):
      _, workflow = self.wf_generator.generate_workflow(
          self.one_time_workflow_1)

      _, cycle = self.wf_generator.generate_cycle(workflow)
      self.wf_generator.activate_workflow(workflow)

    with freeze_time("2015-04-11 03:21:34"):
      user = get_person(self.user.id)
      _, notif_data = common.get_daily_notifications()
      self.assertIn("cycle_started", notif_data[user.email])

    with freeze_time("2015-05-02 03:21:34"):
      _, notif_data = common.get_daily_notifications()
      self.assertIn(user.email, notif_data)
      self.assertIn("cycle_started", notif_data[user.email])
      self.assertNotIn("due_in", notif_data[user.email])
      self.assertNotIn("due_today", notif_data[user.email])

    with freeze_time("2015-05-02 03:21:34"):
      common.send_daily_digest_notifications()
      _, notif_data = common.get_daily_notifications()
      self.assertEqual(notif_data, {})

      # one email to owner and one to assigne
      self.assertEqual(mock_mail.call_count, 2)

    with freeze_time("2015-05-03 03:21:34"):
      cycle = Cycle.query.get(cycle.id)
      task1 = CycleTaskGroupObjectTask.query.get(
          cycle.cycle_task_group_object_tasks[0].id)
      task2 = CycleTaskGroupObjectTask.query.get(
          cycle.cycle_task_group_object_tasks[1].id)

      self.wf_generator.modify_object(
          task1, data={"end_date": date(2015, 5, 15)})
      self.wf_generator.modify_object(
          task2, data={"end_date": date(2015, 5, 15)})

    with freeze_time("2015-05-04 03:21:34"):  # one day befor due date
      _, notif_data = common.get_daily_notifications()
      user = get_person(self.user.id)
      self.assertEqual(notif_data, {})

    with freeze_time("2015-05-05 03:21:34"):  # due date
      _, notif_data = common.get_daily_notifications()
      self.assertEqual(notif_data, {})

    with freeze_time("2015-05-14 03:21:34"):  # due date
      _, notif_data = common.get_daily_notifications()
      self.assertIn(user.email, notif_data)
      self.assertIn("due_in", notif_data[user.email])
      self.assertEqual(len(notif_data[user.email]["due_in"]),
                       len(self.random_objects))

    with freeze_time("2015-05-15 03:21:34"):  # due date
      _, notif_data = common.get_daily_notifications()
      self.assertIn(user.email, notif_data)

      # yesterdays mail has not been sent
      self.assertIn("due_in", notif_data[user.email])

      self.assertIn("due_today", notif_data[user.email])
      self.assertEqual(len(notif_data[user.email]["due_today"]),
                       len(self.random_objects))
Пример #57
0
    def test_sending_overdue_notifications_for_tasks(self, is_vf_needed, _):
        """Overdue notifications should be sent for overdue tasks every day.

    Even if an overdue notification has already been sent, it should still be
    sent in every following daily digest f a task is still overdue.
    """
        with freeze_time("2017-05-15 14:25:36"):
            tmp = self.one_time_workflow.copy()
            tmp['is_verification_needed'] = is_vf_needed
            _, workflow = self.wf_generator.generate_workflow(tmp)
            self.wf_generator.generate_cycle(workflow)
            response, workflow = self.wf_generator.activate_workflow(workflow)
            self.assert200(response)

        tasks = workflow.cycles[0].cycle_task_group_object_tasks
        task1_id = tasks[0].id
        task2_id = tasks[1].id

        task_assignees = [self.user, self.secondary_assignee]
        with freeze_time("2017-05-14 08:09:10"):
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                user_notifs = notif_data.get(user.email, {})
                self.assertNotIn("task_overdue", user_notifs)

        with freeze_time("2017-05-15 08:09:10"):  # task 1 due date
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                user_notifs = notif_data.get(user.email, {})
                self.assertNotIn("task_overdue", user_notifs)

        with freeze_time("2017-05-16 08:09:10"):  # task 2 due date
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                user_notifs = notif_data.get(user.email, {})
                self.assertIn("task_overdue", user_notifs)

                overdue_task_ids = sorted(user_notifs["task_overdue"].keys())
                self.assertEqual(overdue_task_ids, [task1_id])

        with freeze_time("2017-05-17 08:09:10"):  # after both tasks' due dates
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                user_notifs = notif_data.get(user.email, {})
                self.assertIn("task_overdue", user_notifs)

                overdue_task_ids = sorted(user_notifs["task_overdue"].keys())
                self.assertEqual(overdue_task_ids, [task1_id, task2_id])

        common.send_daily_digest_notifications()

        # even after sending the overdue notifications, they are sent again the
        # day after, too
        with freeze_time("2017-05-18 08:09:10"):
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                user_notifs = notif_data.get(user.email, {})
                self.assertIn("task_overdue", user_notifs)

                overdue_task_ids = sorted(user_notifs["task_overdue"].keys())
                self.assertEqual(overdue_task_ids, [task1_id, task2_id])
    def test_move_end_date_to_future(self, mock_mail):
        """Test moving the end date to the future.

    It is done before due_in and due_today notifications have been sent.
    """
        with freeze_time("2015-04-10 03:21:34"):
            _, workflow = self.wf_generator.generate_workflow(
                self.one_time_workflow_1)

            _, cycle = self.wf_generator.generate_cycle(workflow)
            self.wf_generator.activate_workflow(workflow)

        assignee = self.user
        task_assignees = [assignee, self.secondary_assignee]
        with freeze_time("2015-04-11 03:21:34"):
            _, notif_data = common.get_daily_notifications()
            # cycle started notifs available only for contact
            self.assertIn("cycle_started", notif_data[assignee.email])

        with freeze_time("2015-05-02 03:21:34"):
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                self.assertIn(user.email, notif_data)
                self.assertNotIn("due_in", notif_data[user.email])
                self.assertNotIn("due_today", notif_data[user.email])
            # cycle started notifs available only for contact
            self.assertIn("cycle_started", notif_data[assignee.email])

        with freeze_time("2015-05-02 03:21:34"):
            common.send_daily_digest_notifications()
            _, notif_data = common.get_daily_notifications()
            self.assertEqual(notif_data, {})

            # one email to admin and one each to assigne and secondary assignee
            self.assertEqual(mock_mail.call_count, 3)

        with freeze_time("2015-05-03 03:21:34"):
            cycle = Cycle.query.get(cycle.id)
            task1 = CycleTaskGroupObjectTask.query.get(
                cycle.cycle_task_group_object_tasks[0].id)
            task2 = CycleTaskGroupObjectTask.query.get(
                cycle.cycle_task_group_object_tasks[1].id)

            self.wf_generator.modify_object(
                task1, data={"end_date": date(2015, 5, 15)})
            self.wf_generator.modify_object(
                task2, data={"end_date": date(2015, 5, 15)})

        with freeze_time("2015-05-04 03:21:34"):  # one day before due date
            _, notif_data = common.get_daily_notifications()
            self.assertEqual(notif_data, {})

        with freeze_time("2015-05-05 03:21:34"):  # due date
            _, notif_data = common.get_daily_notifications()
            self.assertEqual(notif_data, {})

        with freeze_time("2015-05-14 03:21:34"):  # due date
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                self.assertIn(user.email, notif_data)
                self.assertIn("due_in", notif_data[user.email])
                self.assertEqual(len(notif_data[user.email]["due_in"]),
                                 len(self.random_objects))

        with freeze_time("2015-05-15 03:21:34"):  # due date
            _, notif_data = common.get_daily_notifications()
            for user in task_assignees:
                self.assertIn(user.email, notif_data)

                self.assertIn("due_in", notif_data[user.email])

                self.assertIn("due_today", notif_data[user.email])
                self.assertEqual(len(notif_data[user.email]["due_today"]),
                                 len(self.random_objects))
    def test_models_comments(self, obj_factory, _):
        """Test setting notification entries for model comments.

    Check if the correct notification entries are created when a comment gets
    posted.
    """
        if obj_factory in self.SCOPING_OBJECT_FACTORIES:
            recipient_types = [
                "Admin",
                "Primary Contacts",
                "Secondary Contacts",
                "Assignee",
                "Compliance Contacts",
                "Verifier",
                "Product Managers",
                "Technical / Program Managers",
                "Technical Leads",
                "System Owners",
                "Legal Counsels",
                "Line of Defense One Contacts",
                "Vice Presidents",
            ]
        elif obj_factory == factories.ControlFactory:
            recipient_types = ["Admin", "Control Operators", "Control Owners"]
        else:
            recipient_types = [
                "Admin", "Primary Contacts", "Secondary Contacts"
            ]
        person = all_models.Person.query.first()
        person_email = person.email

        with factories.single_commit():
            obj = obj_factory(
                recipients=",".join(recipient_types),
                send_by_default=False,
            )
            for acl in obj._access_control_list:  # pylint: disable=protected-access
                if acl.ac_role.name in recipient_types:
                    factories.AccessControlPersonFactory(
                        ac_list=acl,
                        person=person,
                    )

        self.generator.generate_comment(obj,
                                        "",
                                        "some comment",
                                        send_notification="true")

        notifications, notif_data = common.get_daily_notifications()
        self.assertEqual(len(notifications), 1,
                         "Missing comment notification entry.")

        recip_notifs = notif_data.get(person_email, {})
        comment_notifs = recip_notifs.get("comment_created", {})
        self.assertEqual(len(comment_notifs), 1)

        # Check if correct revisions count is created
        revisions = Revision.query.filter(
            Revision.resource_type == 'Notification',
            Revision.resource_id.in_([n.id for n in notifications]))
        self.assertEqual(revisions.count(), 1)

        self.client.get("/_notifications/send_daily_digest")
        notifications = self._get_notifications(
            notif_type="comment_created").all()
        self.assertEqual(len(notifications), 0,
                         "Found a comment notification that was not sent.")
Пример #60
0
    def test_grouping_comments(self, _):  # pylint: disable=too-many-locals
        """Test that comments are grouped by parent object in daily digest data."""

        with factories.single_commit():
            audit = factories.AuditFactory()
            audit_slug = audit.slug
            asmt_templ = factories.AssessmentTemplateFactory(audit=audit)
            asmt_templ_slug = asmt_templ.slug

        assessments_data = [
            collections.OrderedDict([
                ("object_type", "Assessment"),
                ("Code*", ""),
                ("Audit*", audit_slug),
                ("Assignees*", "*****@*****.**"),
                ("Creators", "*****@*****.**"),
                ("Template", ""),
                ("Title", "A1"),
            ]),
            collections.OrderedDict([
                ("object_type", "Assessment"),
                ("Code*", ""),
                ("Audit*", audit_slug),
                ("Assignees*", "*****@*****.**"),
                ("Creators", "*****@*****.**"),
                ("Template", asmt_templ_slug),
                ("Title", "A2"),
            ]),
            collections.OrderedDict([
                ("object_type", "Assessment"),
                ("Code*", ""),
                ("Audit*", audit_slug),
                ("Assignees*", "*****@*****.**"),
                ("Creators", "*****@*****.**"),
                ("Template", asmt_templ_slug),
                ("Title", "A3"),
            ]),
        ]

        self.import_data(*assessments_data)

        asmt_with_no_templ = Assessment.query.filter_by(title="A1").first()
        asmt_with_templ_1 = Assessment.query.filter_by(title="A2").first()
        asmt_with_templ_2 = Assessment.query.filter_by(title="A3").first()

        asmt_ids = (asmt_with_no_templ.id, asmt_with_templ_1.id,
                    asmt_with_templ_2.id)

        self.generator.generate_comment(asmt_with_no_templ,
                                        "Verifiers",
                                        "comment X on asmt " +
                                        str(asmt_with_no_templ.id),
                                        send_notification="true")
        self.generator.generate_comment(asmt_with_templ_2,
                                        "Verifiers",
                                        "comment A on asmt " +
                                        str(asmt_with_templ_2.id),
                                        send_notification="true")
        self.generator.generate_comment(asmt_with_templ_1,
                                        "Verifiers",
                                        "comment FOO on asmt " +
                                        str(asmt_with_templ_1.id),
                                        send_notification="true")
        self.generator.generate_comment(asmt_with_templ_1,
                                        "Verifiers",
                                        "comment BAR on asmt " +
                                        str(asmt_with_templ_1.id),
                                        send_notification="true")
        self.generator.generate_comment(asmt_with_no_templ,
                                        "Verifiers",
                                        "comment Y on asmt " +
                                        str(asmt_with_no_templ.id),
                                        send_notification="true")

        _, notif_data = common.get_daily_notifications()

        assignee_notifs = notif_data.get("*****@*****.**", {})
        common.sort_comments(assignee_notifs)
        comment_notifs = assignee_notifs.get("comment_created", {})
        self.assertEqual(len(comment_notifs), 3)  # for 3 different Assessments

        # for each group of comment notifications, check that it contains comments
        # for that particular Assessment
        for parent_obj_key, comments_info in comment_notifs.iteritems():
            self.assertIn(parent_obj_key.id, asmt_ids)
            for comment in comments_info:
                self.assertEqual(comment["parent_id"], parent_obj_key.id)
                self.assertEqual(comment["parent_type"], "Assessment")
                expected_suffix = "asmt " + str(parent_obj_key.id)
                self.assertTrue(
                    comment["description"].endswith(expected_suffix))