def get_task_post_dict(task_group, people_roles, start_date, end_date): """Get TaskGroupTask JSON representation for POST API call. Args: task_group: TaskGroup instance which TaskGroupTask should belong to. people_roles: Mapping like {'ACR name': Person instance} start_date: String date representation. end_date: String date representation. Returns: TaskGroupTask object dict representation for using in POST request. """ response = { "task_group_task": { "response_options": [], "start_date": start_date, "end_date": end_date, "access_control_list": [], "custom_attributes": {}, "task_group": utils.create_stub(task_group), "context": utils.create_stub(task_group.context), "modal_title": "Create New Task", "title": factories.random_str(prefix="tgt_"), "task_type": "text", "description": factories.random_str(length=64), "slug": "" } } for acr_name, person in people_roles.iteritems(): response["task_group_task"]["access_control_list"].append( _get_acl_subdict(acr_name, person, all_models.TaskGroupTask) ) return response
def get_task_post_dict(task_group, people_roles, start_date, end_date): """Get TaskGroupTask JSON representation for POST API call. Args: task_group: TaskGroup instance which TaskGroupTask should belong to. people_roles: Mapping like {'ACR name': Person instance} start_date: String date representation. end_date: String date representation. Returns: TaskGroupTask object dict representation for using in POST request. """ access_control_list = [] for acr_name, person in people_roles.iteritems(): access_control_list.append( _get_acl_subdict(acr_name, person, all_models.TaskGroupTask) ) return { "task_group_task": { "response_options": [], "start_date": start_date, "end_date": end_date, "access_control_list": access_control_list, "custom_attributes": {}, "task_group": utils.create_stub(task_group), "context": utils.create_stub(task_group.context), "modal_title": "Create New Task", "title": factories.random_str(prefix="tgt_"), "task_type": "text", "description": factories.random_str(length=64), "slug": "" } }
def log_json(self): """Serialize to JSON""" out_json = super(Documentable, self).log_json() if hasattr(self, "documents"): out_json["documents"] = [ # pylint: disable=not-an-iterable create_stub(doc) for doc in self.documents if doc ] if hasattr(self, "object_documents"): out_json["object_documents"] = [ # pylint: disable=not-an-iterable create_stub(doc) for doc in self.object_documents if doc ] return out_json
def get_task_group_object_post_dict(task_group, obj_map): """Get TaskGroupObject JSON representation for POST API call. Args: task_group: TaskGroup instance which TaskGroupObject should belong to. obj_map: Object which should be mapped to TaskGroup. Returns: TaskGroupObject object dict representation for using in POST request. """ return { "task_group_object": { "context": utils.create_stub(task_group.context), "task_group": utils.create_stub(task_group), "object": utils.create_stub(obj_map), } }
def get_cycle_post_dict(workflow): """Get Cycle JSON representation for POST API call. Args: workflow: Workflow instance which Cycle should belong to. Returns: Cycle object dict representation for using in POST request. """ return { "cycle": { "context": utils.create_stub(workflow.context), "workflow": utils.create_stub(workflow), "autogenerate": True, "isOverdue": False } }
def get_relationship_post_dict(source, destination): """Get Relationship JSON representation for POST API call. Args: source: Relationship source instance. destination: Relationship destination instance Returns: Relationship object dict representation for using in POST request. """ return { "relationship": { "source": utils.create_stub(source), "destination": utils.create_stub(destination), "context": utils.create_stub(source.context), } }
def log_json(self): """Get a dict with attributes and related objects of self. This method converts additionally person-mapping attributes and owners to person stubs. """ from ggrc import models res = self.log_json_base() for attr in self._people_log_mappings: if hasattr(self, attr): value = getattr(self, attr) # hardcoded [:-3] is used to strip "_id" suffix res[attr[:-3]] = self._person_stub(value) if value else None for attr_name in AttributeInfo.gather_publish_attrs(self.__class__): if is_attr_of_type(self, attr_name, models.Option): attr = getattr(self, attr_name) if attr: stub = create_stub(attr) stub["title"] = attr.title else: stub = None res[attr_name] = stub return res
def log_json(self): """Serialize to JSON""" out_json = super(Folderable, self).log_json() if hasattr(self, "object_folders"): out_json["object_folders"] = [ # pylint: disable=not-an-iterable create_stub(fold) for fold in self.object_folders if fold ] return out_json
def log_json(self): """Serialize to JSON""" out_json = super(Fileable, self).log_json() if hasattr(self, "object_files"): out_json["object_files"] = [ # pylint: disable=not-an-iterable create_stub(file) for file in self.object_files if file ] return out_json
def get_cycle_task_entry_post_dict(cycle_task): """Get CycleTaskEntry JSON representation for POST API call. Args: cycle_task: CycleTaskGroupObjectTask instance which CycleTaskEntry should belong to. Returns: CycleTaskEntry object dict representation for using in POST request. """ return { "cycle_task_entry": { "custom_attributes": {}, "cycle_task_group_object_task": utils.create_stub(cycle_task), "cycle": utils.create_stub(cycle_task.cycle), "context": utils.create_stub(cycle_task.context), "is_declining_review": "", "description": factories.random_str(length=64), } }
def log_json(self): """Serialize to JSON""" out_json = super(Folderable, self).log_json() if hasattr(self, "object_folders"): out_json["object_folders"] = [ # pylint: disable=not-an-iterable create_stub(fold) for fold in self.object_folders if fold ] if hasattr(self, "folders"): out_json["folders"] = self.folders return out_json
def get_task_group_post_dict(workflow, contact): """Get TaskGroup JSON representation for POST API call. Args: workflow: Workflow instance which TaskGroup should belong to. contact: Person instance which should become TaskGroup Assignee. Returns: TaskGroup object dict representation for using in POST request. """ return { "task_group": { "custom_attributes": {}, "contact": utils.create_stub(contact), "workflow": utils.create_stub(workflow), "context": utils.create_stub(workflow.context), "modal_title": "Create Task Group", "title": factories.random_str(prefix="tg_"), "description": factories.random_str(length=64), "slug": "", } }
def log_json(self): """Serialize to JSON""" out_json = super(Reviewable, self).log_json() out_json["review_status"] = self.review_status # put proper review stub to have it in the revision content review_stub = None if self.review: review_stub = utils.create_stub(self.review, self.review.context_id) out_json["review"] = review_stub out_json["review_issue_link"] = self.review_issue_link return out_json
def _get_acl_subdict(acr_name, person, model): """Generate ACL sub-dict representation for using inside JSON. Args: acr_name: Access Control Role name. person: Person instance, who should get `acr_name` in scope of `model`. model: Model, in which scope ACR should be assigned to `person`. Returns: ACL entry sub-dict representation. It is used for inserting into object JSON representation under 'access_control_list' key. """ with app.app_context(): acr = role.get_ac_roles_for(model.__name__)[acr_name] return {"ac_role_id": acr.id, "person": utils.create_stub(person)}
def acl_json(self): """Get json representation of access_control_list. This function is a hack to preserve backwards compatibility with old revision logs. """ acl_json = [] for person, acl in self.access_control_list: person_entry = acl.log_json() person_entry["person"] = utils.create_stub(person) person_entry["person_email"] = person.email person_entry["person_id"] = person.id person_entry["person_name"] = person.name acl_json.append(person_entry) return acl_json
def people_json(self): """Get json representation of people in ACL.""" people_json = [] common_json = self.log_json() for _acp in self.access_control_people: person = _acp.person person_entry = dict( person=utils.create_stub(person), person_email=person.email, person_id=person.id, person_name=person.name, ) person_entry.update(common_json) people_json.append(person_entry) return people_json
def _get_acl_subdict(acr_name, person, model): """Generate ACL sub-dict representation for using inside JSON. Args: acr_name: Access Control Role name. person: Person instance, who should get `acr_name` in scope of `model`. model: Model, in which scope ACR should be assigned to `person`. Returns: ACL entry sub-dict representation. It is used for inserting into object JSON representation under 'access_control_list' key. """ acr = role.get_ac_roles_for(model.__name__)[acr_name] return { "ac_role_id": acr.id, "person": utils.create_stub(person) }
def people_json(self): """Get json representation of people in ACL.""" people_json = [] common_json = self.log_json() people = [_acp.person for _acp in self.access_control_people] if any(not utils.is_deferred_loaded(person) for person in people): # Since fields needed to create person json representation for ACL are # deferred and to avoid unnecessary DB queries, people reloading is # performed here. people = self._query_people() for person in people: person_entry = dict( person=utils.create_stub(person), person_email=person.email, person_id=person.id, person_name=person.name, ) person_entry.update(common_json) people_json.append(person_entry) return people_json
def test_task_count_multiple_wfs(self): """Test task count with both verified and non verified workflows. This checks task counts with 4 tasks 2017, 8, 15 - verification needed 2017, 11, 18 - verification needed 2017, 8, 15 - No verification needed 2017, 11, 18 - No verification needed """ user = all_models.Person.query.first() user_id = user.id role_id = all_models.AccessControlRole.query.filter( all_models.AccessControlRole.name == "Task Assignees", all_models.AccessControlRole.object_type == "TaskGroupTask", ).one().id workflow_template = { "title": "verified workflow", "owners": [create_stub(user)], "is_verification_needed": True, "task_groups": [{ "title": "one time task group", "contact": create_stub(user), "task_group_tasks": [{ "title": "task 1", "description": "some task", "access_control_list": [acl_helper.get_acl_json(role_id, user.id)], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 15), }, { "title": "dummy task 5", "description": "some task 4", "access_control_list": [acl_helper.get_acl_json(role_id, user.id)], "start_date": date(2017, 6, 5), "end_date": date(2017, 11, 18), }], "task_group_objects": [] }] } with freeze_time("2017-10-16 05:09:10"): self.client.get("/login") verified_workflow = workflow_template.copy() verified_workflow["is_verification_needed"] = True _, workflow = self.generator.generate_workflow(verified_workflow) _, cycle = self.generator.generate_cycle(workflow) verified_tasks = { task.title: task for task in cycle.cycle_task_group_object_tasks } _, workflow = self.generator.activate_workflow(workflow) non_verified_workflow = workflow_template.copy() non_verified_workflow["is_verification_needed"] = False _, workflow = self.generator.generate_workflow( non_verified_workflow) _, cycle = self.generator.generate_cycle(workflow) non_verified_tasks = { task.title: task for task in cycle.cycle_task_group_object_tasks } _, workflow = self.generator.activate_workflow(workflow) with freeze_time("2017-7-16 07:09:10"): self.client.get("/login") response = self.client.get( "/api/people/{}/task_count".format(user_id)) self.assertEqual(response.json, { "open_task_count": 4, "has_overdue": False }) with freeze_time("2017-10-16 08:09:10"): self.client.get("/login") response = self.client.get( "/api/people/{}/task_count".format(user_id)) self.assertEqual(response.json, { "open_task_count": 4, "has_overdue": True }) # transition 1, task that needs verification goes to finished state. This # transition should not change anything self.generator.modify_object(verified_tasks["task 1"], data={"status": "Finished"}) response = self.client.get( "/api/people/{}/task_count".format(user_id)) self.assertEqual(response.json, { "open_task_count": 4, "has_overdue": True }) # transition 2, task that needs verification goes to verified state. This # transition should reduce task count. self.generator.modify_object(verified_tasks["task 1"], data={"status": "Verified"}) response = self.client.get( "/api/people/{}/task_count".format(user_id)) self.assertEqual(response.json, { "open_task_count": 3, "has_overdue": True }) # transition 3, task that does not need verification goes into Finished # state. This transition should reduce task count and remove all overdue # tasks self.generator.modify_object(non_verified_tasks["task 1"], data={"status": "Finished"}) response = self.client.get( "/api/people/{}/task_count".format(user_id)) self.assertEqual(response.json, { "open_task_count": 2, "has_overdue": False })
def test_task_count(self, is_verification_needed, transitions): """Test person task counts. This tests checks for correct task counts - with inactive workflows and - with overdue tasks - without overdue tasks - with finished overdue tasks The four checks are done in a single test due to complex differences between tests that make ddt cumbersome and the single test also improves integration test performance due to slow workflow setup stage. """ # pylint: disable=too-many-locals user = all_models.Person.query.first() dummy_user = factories.PersonFactory() user_id = user.id role_id = all_models.AccessControlRole.query.filter( all_models.AccessControlRole.name == "Task Assignees", all_models.AccessControlRole.object_type == "TaskGroupTask", ).one().id secondary_role_id = all_models.AccessControlRole.query.filter( all_models.AccessControlRole.name == "Task Secondary Assignees", all_models.AccessControlRole.object_type == "TaskGroupTask", ).one().id one_time_workflow = { "title": "Person resource test workflow", "notify_on_change": True, "description": "some test workflow", "owners": [create_stub(user)], "is_verification_needed": is_verification_needed, "task_groups": [{ "title": "one time task group", "contact": create_stub(user), "task_group_tasks": [ { "title": "task 1", "description": "some task", "access_control_list": [ acl_helper.get_acl_json(role_id, user.id), acl_helper.get_acl_json(secondary_role_id, user.id) ], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 15), }, { "title": "task 2", "description": "some task 3", "access_control_list": [ acl_helper.get_acl_json(role_id, user.id), acl_helper.get_acl_json(secondary_role_id, user.id), acl_helper.get_acl_json(secondary_role_id, dummy_user.id) ], "start_date": date(2017, 5, 5), "end_date": date(2017, 9, 16), }, { "title": "task 3", "description": "some task 4", "access_control_list": [ acl_helper.get_acl_json(role_id, user.id), acl_helper.get_acl_json(role_id, dummy_user.id) ], "start_date": date(2017, 6, 5), "end_date": date(2017, 10, 16), }, { "title": "dummy task 4", # task should not counted "description": "some task 4", "access_control_list": [acl_helper.get_acl_json(role_id, dummy_user.id)], "start_date": date(2017, 6, 5), "end_date": date(2017, 11, 17), }, { "title": "dummy task 5", # task should not counted "description": "some task 4", "access_control_list": [acl_helper.get_acl_json(role_id, dummy_user.id)], "start_date": date(2017, 6, 5), "end_date": date(2017, 11, 18), } ], "task_group_objects": [] }] } inactive_workflow = { "title": "Activated workflow with archived cycles", "notify_on_change": True, "description": "Extra test workflow", "owners": [create_stub(user)], "task_groups": [{ "title": "Extra task group", "contact": create_stub(user), "task_group_tasks": [{ "title": "not counted existing task", "description": "", "access_control_list": [acl_helper.get_acl_json(role_id, user.id)], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 15), }], "task_group_objects": [] }] } with freeze_time("2017-10-16 05:09:10"): self.client.get("/login") # Activate normal one time workflow _, workflow = self.generator.generate_workflow(one_time_workflow) _, cycle = self.generator.generate_cycle(workflow) tasks = {t.title: t for t in cycle.cycle_task_group_object_tasks} _, workflow = self.generator.activate_workflow(workflow) # Activate and close the inactive workflow _, workflow = self.generator.generate_workflow(inactive_workflow) _, cycle = self.generator.generate_cycle(workflow) _, workflow = self.generator.activate_workflow(workflow) self.generator.modify_object(cycle, data={"is_current": False}) with freeze_time("2017-7-16 07:09:10"): self.client.get("/login") response = self.client.get( "/api/people/{}/task_count".format(user_id)) self.assertEqual(response.json, { "open_task_count": 3, "has_overdue": False }) with freeze_time("2017-10-16 08:09:10"): # same day as task 3 end date self.client.get("/login") response = self.client.get( "/api/people/{}/task_count".format(user_id)) self.assertEqual(response.json, { "open_task_count": 3, "has_overdue": True }) for task, status, count, overdue, my_work_count in transitions: self.generator.modify_object(tasks[task], data={"status": status}) task_count_response = \ self.client.get("/api/people/{}/task_count".format(user_id)) my_work_count_response = \ self.client.get("/api/people/{}/my_work_count".format(user_id)) self.assertEqual(task_count_response.json, { "open_task_count": count, "has_overdue": overdue }) self.assertEqual( my_work_count_response.json["CycleTaskGroupObjectTask"], my_work_count)
def _setup_data(self): """Help method to setup workflows configuration.""" # pylint: disable=too-many-locals # pylint: disable=attribute-defined-outside-init first_wf_admin = all_models.Person.query.first() _, second_wf_admin = self.object_generator.generate_person( user_role="Administrator", data={"email": "*****@*****.**"}) first_wf_admin_id = first_wf_admin.id role = all_models.AccessControlRole.query.filter( all_models.AccessControlRole.name == "Task Assignees", all_models.AccessControlRole.object_type == "TaskGroupTask", ).one() role_id = role.id workflow_template1 = { "title": "test wf 1", "is_verification_needed": True, "task_groups": [{ "title": "task group 1", "contact": create_stub(first_wf_admin), "task_group_tasks": [{ "title": "task 1", "description": "some task", "access_control_list": [ acl_helper.get_acl_json(role_id, first_wf_admin_id)], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 15), }, { "title": "task 2", "description": "some task", "access_control_list": [ acl_helper.get_acl_json(role_id, first_wf_admin_id)], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 16), }, {"title": "task 3", "description": "some task", "access_control_list": [ acl_helper.get_acl_json(role_id, first_wf_admin_id)], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 17), } ], "task_group_objects": [] }, { "title": "task group 2", "contact": create_stub(first_wf_admin), "task_group_tasks": [{ "title": "task 4", "description": "some task", "access_control_list": [ acl_helper.get_acl_json(role_id, first_wf_admin_id)], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 17), }], "task_group_objects": [] }] } workflow_template2 = { "title": "test wf 2", "is_verification_needed": False, "task_groups": [{ "title": "task group 1", "contact": create_stub(first_wf_admin), "task_group_tasks": [{ "title": "task 5", "description": "some task", "access_control_list": [ acl_helper.get_acl_json(role_id, first_wf_admin_id)], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 17), }, { "title": "task 6", "description": "some task", "access_control_list": [ acl_helper.get_acl_json(role_id, first_wf_admin_id)], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 15) }, { "title": "task 7", "description": "some task", "access_control_list": [ acl_helper.get_acl_json(role_id, first_wf_admin_id)], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 17) }, { "title": "task 8", "description": "some task", "access_control_list": [ acl_helper.get_acl_json(role_id, first_wf_admin_id)], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 14) }], "task_group_objects": [] }] } with factories.single_commit(): _, workflow1 = self.generator.generate_workflow(workflow_template1) _, workflow2 = self.generator.generate_workflow(workflow_template2) _, cycle1 = self.generator.generate_cycle(workflow1) _, cycle2 = self.generator.generate_cycle(workflow2) _, workflow1 = self.generator.activate_workflow(workflow1) _, workflow2 = self.generator.activate_workflow(workflow2) cycle1_id = cycle1.id cycle2_id = cycle2.id workflow1 = all_models.Workflow.query.get(workflow1.id) self.workflow1_id = workflow1.id self.workflow2_id = workflow2.id # first workflow has 2 workflow admins, second has 1 # workflow admin now factories.AccessControlPersonFactory( ac_list=workflow1.acr_name_acl_map["Admin"], person=second_wf_admin ) with freeze_time("2017-8-16"): cycle1 = all_models.Cycle.query.get(cycle1_id) cycle2 = all_models.Cycle.query.get(cycle2_id) task2 = cycle1.cycle_task_group_object_tasks[1] task3 = cycle1.cycle_task_group_object_tasks[2] task4 = cycle1.cycle_task_group_object_tasks[3] task5 = cycle2.cycle_task_group_object_tasks[0] task7 = cycle2.cycle_task_group_object_tasks[2] task8 = cycle2.cycle_task_group_object_tasks[3] self.api.put(task2, { "status": "Finished" }) self.api.put(task3, { "status": "Deprecated" }) self.api.put(task4, { "status": "Verified" }) self.api.put(task5, { "status": "Finished" }) self.api.put(task7, { "status": "Deprecated" }) self.api.put(task8, { "status": "Finished" })
def test_task_count_multiple_wfs(self): """Test task count with both verified and non verified workflows. This checks task counts with 4 tasks 2017, 8, 15 - verification needed 2017, 11, 18 - verification needed 2017, 8, 15 - No verification needed 2017, 11, 18 - No verification needed """ user = all_models.Person.query.first() user_id = user.id role_id = all_models.AccessControlRole.query.filter( all_models.AccessControlRole.name == "Task Assignees", all_models.AccessControlRole.object_type == "TaskGroupTask", ).one().id workflow_template = { "title": "verified workflow", "owners": [create_stub(user)], "is_verification_needed": True, "task_groups": [{ "title": "one time task group", "contact": create_stub(user), "task_group_tasks": [{ "title": "task 1", "description": "some task", "access_control_list": [ acl_helper.get_acl_json(role_id, user.id)], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 15), }, { "title": "dummy task 5", "description": "some task 4", "access_control_list": [ acl_helper.get_acl_json(role_id, user.id)], "start_date": date(2017, 6, 5), "end_date": date(2017, 11, 18), }], "task_group_objects": [] }] } with freeze_time("2017-10-16 05:09:10"): self.client.get("/login") verified_workflow = workflow_template.copy() verified_workflow["is_verification_needed"] = True _, workflow = self.generator.generate_workflow(verified_workflow) _, cycle = self.generator.generate_cycle(workflow) verified_tasks = { task.title: task for task in cycle.cycle_task_group_object_tasks } _, workflow = self.generator.activate_workflow(workflow) non_verified_workflow = workflow_template.copy() non_verified_workflow["is_verification_needed"] = False _, workflow = self.generator.generate_workflow(non_verified_workflow) _, cycle = self.generator.generate_cycle(workflow) non_verified_tasks = { task.title: task for task in cycle.cycle_task_group_object_tasks } _, workflow = self.generator.activate_workflow(workflow) with freeze_time("2017-7-16 07:09:10"): self.client.get("/login") response = self.client.get("/api/people/{}/task_count".format(user_id)) self.assertEqual( response.json, {"open_task_count": 4, "has_overdue": False} ) with freeze_time("2017-10-16 08:09:10"): self.client.get("/login") response = self.client.get("/api/people/{}/task_count".format(user_id)) self.assertEqual( response.json, {"open_task_count": 4, "has_overdue": True} ) # transition 1, task that needs verification goes to finished state. This # transition should not change anything self.generator.modify_object( verified_tasks["task 1"], data={"status": "Finished"} ) response = self.client.get("/api/people/{}/task_count".format(user_id)) self.assertEqual( response.json, {"open_task_count": 4, "has_overdue": True} ) # transition 2, task that needs verification goes to verified state. This # transition should reduce task count. self.generator.modify_object( verified_tasks["task 1"], data={"status": "Verified"} ) response = self.client.get("/api/people/{}/task_count".format(user_id)) self.assertEqual( response.json, {"open_task_count": 3, "has_overdue": True} ) # transition 3, task that does not need verification goes into Finished # state. This transition should reduce task count and remove all overdue # tasks self.generator.modify_object( non_verified_tasks["task 1"], data={"status": "Finished"} ) response = self.client.get("/api/people/{}/task_count".format(user_id)) self.assertEqual( response.json, {"open_task_count": 2, "has_overdue": False} )
def test_task_count(self, is_verification_needed, transitions): """Test person task counts. This tests checks for correct task counts - with inactive workflows and - with overdue tasks - without overdue tasks - with finished overdue tasks The four checks are done in a single test due to complex differences between tests that make ddt cumbersome and the single test also improves integration test performance due to slow workflow setup stage. """ # pylint: disable=too-many-locals user = all_models.Person.query.first() dummy_user = factories.PersonFactory() user_id = user.id role_id = all_models.AccessControlRole.query.filter( all_models.AccessControlRole.name == "Task Assignees", all_models.AccessControlRole.object_type == "TaskGroupTask", ).one().id secondary_role_id = all_models.AccessControlRole.query.filter( all_models.AccessControlRole.name == "Task Secondary Assignees", all_models.AccessControlRole.object_type == "TaskGroupTask", ).one().id one_time_workflow = { "title": "Person resource test workflow", "notify_on_change": True, "description": "some test workflow", "owners": [create_stub(user)], "is_verification_needed": is_verification_needed, "task_groups": [{ "title": "one time task group", "contact": create_stub(user), "task_group_tasks": [{ "title": "task 1", "description": "some task", "access_control_list": [ acl_helper.get_acl_json(role_id, user.id), acl_helper.get_acl_json(secondary_role_id, user.id) ], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 15), }, { "title": "task 2", "description": "some task 3", "access_control_list": [ acl_helper.get_acl_json(role_id, user.id), acl_helper.get_acl_json(secondary_role_id, user.id), acl_helper.get_acl_json(secondary_role_id, dummy_user.id) ], "start_date": date(2017, 5, 5), "end_date": date(2017, 9, 16), }, { "title": "task 3", "description": "some task 4", "access_control_list": [ acl_helper.get_acl_json(role_id, user.id), acl_helper.get_acl_json(role_id, dummy_user.id) ], "start_date": date(2017, 6, 5), "end_date": date(2017, 10, 16), }, { "title": "dummy task 4", # task should not counted "description": "some task 4", "access_control_list": [ acl_helper.get_acl_json(role_id, dummy_user.id)], "start_date": date(2017, 6, 5), "end_date": date(2017, 11, 17), }, { "title": "dummy task 5", # task should not counted "description": "some task 4", "access_control_list": [ acl_helper.get_acl_json(role_id, dummy_user.id)], "start_date": date(2017, 6, 5), "end_date": date(2017, 11, 18), }], "task_group_objects": [] }] } inactive_workflow = { "title": "Activated workflow with archived cycles", "notify_on_change": True, "description": "Extra test workflow", "owners": [create_stub(user)], "task_groups": [{ "title": "Extra task group", "contact": create_stub(user), "task_group_tasks": [{ "title": "not counted existing task", "description": "", "access_control_list": [ acl_helper.get_acl_json(role_id, user.id)], "start_date": date(2017, 5, 5), "end_date": date(2017, 8, 15), }], "task_group_objects": [] }] } with freeze_time("2017-10-16 05:09:10"): self.client.get("/login") # Activate normal one time workflow _, workflow = self.generator.generate_workflow(one_time_workflow) _, cycle = self.generator.generate_cycle(workflow) tasks = {t.title: t for t in cycle.cycle_task_group_object_tasks} _, workflow = self.generator.activate_workflow(workflow) # Activate and close the inactive workflow _, workflow = self.generator.generate_workflow(inactive_workflow) _, cycle = self.generator.generate_cycle(workflow) _, workflow = self.generator.activate_workflow(workflow) self.generator.modify_object(cycle, data={"is_current": False}) with freeze_time("2017-7-16 07:09:10"): self.client.get("/login") response = self.client.get("/api/people/{}/task_count".format(user_id)) self.assertEqual( response.json, {"open_task_count": 3, "has_overdue": False} ) with freeze_time("2017-10-16 08:09:10"): # same day as task 3 end date self.client.get("/login") response = self.client.get("/api/people/{}/task_count".format(user_id)) self.assertEqual( response.json, {"open_task_count": 3, "has_overdue": True} ) for task, status, count, overdue, my_work_count in transitions: self.generator.modify_object(tasks[task], data={"status": status}) task_count_response = \ self.client.get("/api/people/{}/task_count".format(user_id)) my_work_count_response = \ self.client.get("/api/people/{}/my_work_count".format(user_id)) self.assertEqual( task_count_response.json, {"open_task_count": count, "has_overdue": overdue} ) self.assertEqual( my_work_count_response.json["CycleTaskGroupObjectTask"], my_work_count )
def _log_docs(documents): return [create_stub(d) for d in documents if d]