def create_draft_project(draft_project_dto: DraftProjectDTO) -> int: """ Validates and then persists draft projects in the DB :param draft_project_dto: Draft Project DTO with data from API :raises InvalidGeoJson :returns ID of new draft project """ try: area_of_interest = AreaOfInterest( draft_project_dto.area_of_interest) except InvalidGeoJson as e: raise e draft_project = Project() draft_project.create_draft_project(draft_project_dto, area_of_interest) # if arbitrary_tasks requested, create tasks from aoi otherwise use tasks in DTO if draft_project_dto.has_arbitrary_tasks: tasks = GridService.tasks_from_aoi_features( draft_project_dto.area_of_interest) else: tasks = draft_project_dto.tasks ProjectAdminService._attach_tasks_to_project(draft_project, tasks) draft_project.create() return draft_project.id
def test_split_task_helper(self, mock_task_get, mock_task_get_max_task_id_for_project, mock_task_create, mock_task_delete, mock_project_get, mock_project_save, mock_project_tasks, mock_instructions): if self.skip_tests: return # arrange task_stub = Task() task_stub.id = 1 task_stub.project_id = 1 task_stub.task_status = 1 task_stub.locked_by = 1234 task_stub.lock_holder = 1234 task_stub.splittable = True task_stub.x = 1010 task_stub.y = 1399 task_stub.zoom = 11 mock_task_get.return_value = task_stub mock_task_get_max_task_id_for_project.return_value = 1 mock_project_get.return_value = Project() mock_project_tasks.return_value = [task_stub] splitTaskDTO = SplitTaskDTO() splitTaskDTO.user_id = 1234 splitTaskDTO.project_id = 1 splitTaskDTO.task_id = 1 # act result = SplitService.split_task(splitTaskDTO) # assert self.assertEqual(4, len(result.tasks))
def create_draft_project(draft_project_dto: DraftProjectDTO) -> int: """ Validates and then persists draft projects in the DB :param draft_project_dto: Draft Project DTO with data from API :raises InvalidGeoJson :returns ID of new draft project """ # If we're cloning we'll copy all the project details from the clone, otherwise create brand new project if draft_project_dto.cloneFromProjectId: draft_project = Project.clone(draft_project_dto.cloneFromProjectId, draft_project_dto.user_id) else: draft_project = Project() draft_project.create_draft_project(draft_project_dto) draft_project.set_project_aoi(draft_project_dto) # if arbitrary_tasks requested, create tasks from aoi otherwise use tasks in DTO if draft_project_dto.has_arbitrary_tasks: tasks = GridService.tasks_from_aoi_features( draft_project_dto.area_of_interest) draft_project.task_creation_mode = TaskCreationMode.ARBITRARY.value else: tasks = draft_project_dto.tasks ProjectAdminService._attach_tasks_to_project(draft_project, tasks) if draft_project_dto.cloneFromProjectId: draft_project.save() # Update the clone else: draft_project.create() # Create the new project draft_project.set_default_changeset_comment() return draft_project.id
def create_canned_project() -> Tuple[Project, User]: """ Generates a canned project in the DB to help with integration tests """ test_aoi_geojson = geojson.loads( json.dumps(get_canned_json('test_aoi.json'))) task_feature = geojson.loads( json.dumps(get_canned_json('splittable_task.json'))) test_user = create_canned_user() test_project_dto = DraftProjectDTO() test_project_dto.project_name = 'Test' test_project_dto.user_id = test_user.id test_project_dto.area_of_interest = test_aoi_geojson test_project = Project() test_project.create_draft_project(test_project_dto) test_project.set_project_aoi(test_project_dto) test_project.total_tasks = 1 # Setup test task test_task = Task.from_geojson_feature(1, task_feature) test_task.task_status = TaskStatus.MAPPED.value test_task.mapped_by = test_user.id test_project.tasks.append(test_task) test_project.create() return test_project, test_user
def test_update_after_flagging_bad_imagery(self): # Arrange test_project = Project() test_project.tasks_bad_imagery = 0 # Act StatsService._set_counters_after_bad_imagery(test_project) # Assert self.assertEqual(test_project.tasks_bad_imagery, 1)
def test_user_correctly_identified_as_pm(self, mock_user): # Arrange test_proj = Project() test_user = User() test_user.role = UserRole.PROJECT_MANAGER.value mock_user.return_value = test_user # Act / Assert self.assertTrue(UserService.is_user_a_project_manager(123)) self.assertTrue(test_proj)
def test_get_intersecting_projects(self, get_dto_for_locale, _get_intersecting_projects, get_user_by_username, validate_bbox_area, _make_4326_polygon_from_bbox): if self.skip_tests: return # arrange _make_4326_polygon_from_bbox mock _make_4326_polygon_from_bbox.return_value = Polygon([ (34.68826225820438, -12.59912449955007), (34.68826225820438, -11.57858317689196), (32.50198296132938, -11.57858317689196), (32.50198296132938, -12.59912449955007), (34.68826225820438, -12.59912449955007) ]) # arrange validate_bbox_area mock validate_bbox_area.return_value = True # arrange get_user_by_username mock get_user_by_username.return_value = User(id=3488526) # arrange _get_intersecting_projects mock polygon = json.dumps(get_canned_json('search_bbox_feature.json')) project = Project(id=2274, status=0, default_locale='en', geometry=polygon) projects = [project] _get_intersecting_projects.return_value = projects # arrange get_dto_for_locale mock get_dto_for_locale.return_value = ProjectInfo( name='PEPFAR Kenya: Homa Bay') # arrange dto dto = ProjectSearchBBoxDTO() dto.bbox = map(float, '34.404,-1.034, 34.717,-0.624'.split(',')) dto.preferred_locale = 'en' dto.input_srid = 4326 dto.project_author = 3488526 dto.validate() # arrange expected result expected = json.dumps(get_canned_json('search_bbox_result.json')) # act result = ProjectSearchService.get_projects_geojson(dto) # assert self.assertEqual(str(expected), str(expected))
def test_update_after_mapping_increments_counter(self): # Arrange test_project = Project() test_project.tasks_mapped = 0 test_user = User() test_user.tasks_mapped = 0 # Act StatsService._set_counters_after_mapping(test_project, test_user) # Assert self.assertEqual(test_project.tasks_mapped, 1) self.assertEqual(test_user.tasks_mapped, 1)
def test_update_after_mapping_increments_counter(self): # Arrange test_project = Project() test_project.tasks_mapped = 0 test_user = User() test_user.tasks_mapped = 0 # Act StatsService._update_tasks_stats(test_project, test_user, TaskStatus.READY, TaskStatus.MAPPED) # Assert self.assertEqual(test_project.tasks_mapped, 1) self.assertEqual(test_user.tasks_mapped, 1)
def test_update_after_flagging_bad_imagery(self): # Arrange test_project = Project() test_project.tasks_bad_imagery = 0 test_user = User() test_user.tasks_invalidated = 0 # Act StatsService._update_tasks_stats(test_project, test_user, TaskStatus.READY, TaskStatus.BADIMAGERY) # Assert self.assertEqual(test_project.tasks_bad_imagery, 1)
def test_update_after_invalidating_bad_imagery_task_sets_counters_correctly(self, last_status): # Arrange test_project = Project() test_project.tasks_bad_imagery = 1 test_user = User() test_user.tasks_invalidated = 0 last_status.return_value = TaskStatus.BADIMAGERY # Act StatsService._set_counters_after_invalidated(1, test_project, test_user) # Assert self.assertEqual(test_project.tasks_bad_imagery, 0) self.assertEqual(test_user.tasks_invalidated, 1)
def test_update_after_invalidating_mapped_task_sets_counters_correctly(self, last_status): # Arrange test_project = Project() test_project.tasks_mapped = 1 test_user = User() test_user.tasks_invalidated = 0 last_status.return_value = TaskStatus.MAPPED # Act StatsService._set_counters_after_invalidated(1, test_project, test_user) # Assert self.assertEqual(test_project.tasks_mapped, 0) self.assertEqual(test_user.tasks_invalidated, 1)
def test_update_after_invalidating_validated_task_sets_counters_correctly( self): # Arrange test_project = Project() test_project.tasks_validated = 1 test_user = User() test_user.tasks_invalidated = 0 # Act StatsService._update_tasks_stats(test_project, test_user, TaskStatus.VALIDATED, TaskStatus.INVALIDATED) # Assert self.assertEqual(test_project.tasks_validated, 0) self.assertEqual(test_user.tasks_invalidated, 1)
def create_draft_project(draft_project_dto: DraftProjectDTO) -> int: """ Validates and then persists draft projects in the DB :param draft_project_dto: Draft Project DTO with data from API :raises InvalidGeoJson :returns ID of new draft project """ # First things first, we need to validate that the author_id is a PM. issue #1715 if not UserService.is_user_a_project_manager( draft_project_dto.user_id): raise (ProjectAdminServiceError( f'User {UserService.get_user_by_id(draft_project_dto.user_id).username} is not a project manager' )) # If we're cloning we'll copy all the project details from the clone, otherwise create brand new project if draft_project_dto.cloneFromProjectId: draft_project = Project.clone(draft_project_dto.cloneFromProjectId, draft_project_dto.user_id) else: draft_project = Project() draft_project.create_draft_project(draft_project_dto) draft_project.set_project_aoi(draft_project_dto) # if arbitrary_tasks requested, create tasks from aoi otherwise use tasks in DTO if draft_project_dto.has_arbitrary_tasks: tasks = GridService.tasks_from_aoi_features( draft_project_dto.area_of_interest) draft_project.task_creation_mode = TaskCreationMode.ARBITRARY.value else: tasks = draft_project_dto.tasks ProjectAdminService._attach_tasks_to_project(draft_project, tasks) if draft_project_dto.cloneFromProjectId: draft_project.save() # Update the clone else: draft_project.create() # Create the new project draft_project.set_default_changeset_comment() return draft_project.id
def test_split_task_helper(self, mock_task_get, mock_task_get_max_task_id_for_project, mock_task_create, mock_task_delete, mock_project_get, mock_project_save, mock_project_tasks, mock_instructions): if self.skip_tests: return # arrange task_stub = Task() task_stub.id = 1 task_stub.project_id = 1 task_stub.task_status = 1 task_stub.locked_by = 1234 task_stub.lock_holder = 1234 task_stub.is_square = True task_stub.x = 16856 task_stub.y = 17050 task_stub.zoom = 15 task_stub.geometry = shape.from_shape( Polygon([(5.1855468740711421, 7.2970875628719796), (5.1855468740711421, 7.3079847788619219), (5.1965332021941588, 7.3079847788619219), (5.1965332021941588, 7.2970875628719796), (5.1855468740711421, 7.2970875628719796)])) mock_task_get.return_value = task_stub mock_task_get_max_task_id_for_project.return_value = 1 mock_project_get.return_value = Project() mock_project_tasks.return_value = [task_stub] splitTaskDTO = SplitTaskDTO() splitTaskDTO.user_id = 1234 splitTaskDTO.project_id = 1 splitTaskDTO.task_id = 1 # act result = SplitService.split_task(splitTaskDTO) # assert self.assertEqual(4, len(result.tasks))
def test_tasks_state_representation(self): # Arrange test_project = Project() test_project.tasks_mapped = 0 test_project.tasks_validated = 0 test_project.tasks_bad_imagery = 0 test_mapper = User() test_mapper.tasks_mapped = 0 test_mapper.tasks_validated = 0 test_mapper.tasks_invalidated = 0 test_validator = User() test_validator.tasks_mapped = 0 test_validator.tasks_validated = 0 test_validator.tasks_invalidated = 0 test_admin = User() test_admin.tasks_mapped = 0 test_admin.tasks_validated = 0 test_admin.tasks_invalidated = 0 # Mapper marks task as mapped StatsService._update_tasks_stats(test_project, test_mapper, TaskStatus.READY, TaskStatus.MAPPED) # Validator marks task as bad imagery StatsService._update_tasks_stats(test_project, test_validator, TaskStatus.MAPPED, TaskStatus.BADIMAGERY) # Admin undos marking task as bad imagery StatsService._update_tasks_stats(test_project, test_admin, TaskStatus.BADIMAGERY, TaskStatus.MAPPED, 'undo') # Validator marks task as invalid StatsService._update_tasks_stats(test_project, test_validator, TaskStatus.MAPPED, TaskStatus.INVALIDATED) # Mapper marks task as mapped StatsService._update_tasks_stats(test_project, test_mapper, TaskStatus.INVALIDATED, TaskStatus.MAPPED) # Admin undos marking task as mapped (test_mapper is given to the function though, as the author of the # last_change - compare with MappingServer.undo_mapping() method) StatsService._update_tasks_stats(test_project, test_mapper, TaskStatus.MAPPED, TaskStatus.INVALIDATED, 'undo') # Mapper marks task as mapped StatsService._update_tasks_stats(test_project, test_mapper, TaskStatus.INVALIDATED, TaskStatus.MAPPED) # Validator marks task as valid StatsService._update_tasks_stats(test_project, test_validator, TaskStatus.MAPPED, TaskStatus.VALIDATED) # Assert self.assertEqual(test_project.tasks_mapped, 0) self.assertEqual(test_project.tasks_validated, 1) self.assertEqual(test_project.tasks_bad_imagery, 0) self.assertEqual(test_mapper.tasks_mapped, 2) self.assertEqual(test_mapper.tasks_validated, 0) self.assertEqual(test_mapper.tasks_invalidated, 0) self.assertEqual(test_validator.tasks_mapped, 0) self.assertEqual(test_validator.tasks_validated, 1) self.assertEqual(test_validator.tasks_invalidated, 1) self.assertEqual(test_admin.tasks_mapped, 0) self.assertEqual(test_admin.tasks_validated, 0) self.assertEqual(test_admin.tasks_invalidated, 0)