Skip to content

Commit

Permalink
RDISCROWD-5629 add allow-assign-to-user to assign task (#809)
Browse files Browse the repository at this point in the history
* RDISCROWD-5629 add allow-assign-to-user to assign task

* address code review

* enhanced logging
  • Loading branch information
XiChenn committed Feb 2, 2023
1 parent de009e8 commit b563d02
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 1 deletion.
43 changes: 43 additions & 0 deletions pybossa/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -713,3 +713,46 @@ def _get_valid_service(task_id, service_name, payload, proxy_service_config):
'Task {} loaded for user {} failed calling {} service with payload {}'.format(task_id, current_user.id, service_name, payload))

return abort(403, 'The request data failed validation')


@jsonpify
@login_required
@csrf.exempt
@blueprint.route('/task/<int:task_id>/assign', methods=['POST'])
@ratelimit(limit=ratelimits.get('LIMIT'), per=ratelimits.get('PER'))
def assign_task(task_id=None):
"""Assign task to users for locked, user_pref and task_queue schedulers."""
projectname = request.json.get('projectname', None)
a_project = project_repo.get_by_shortname(projectname)
if not a_project:
return abort(400, f"Invalid project name {projectname}")

_, ttl = fetch_lock_for_user(a_project.id, task_id, current_user.id)
if not ttl:
current_app.logger.warn(
"User %s requested for assigning task %s that has not been locked by the user.",
current_user.fullname, task_id)
return abort(403, 'A lock is required for assigning a task to a user.')

# only assign the user to the task for user_pref and task_queue scheduler
scheduler, _ = get_scheduler_and_timeout(a_project)
if scheduler not in (Schedulers.user_pref, Schedulers.task_queue):
current_app.logger.warn(
"Task scheduler for project is set to %s. Cannot assign users %s for task %s",
scheduler, current_user.fullname, task_id)
return abort(403, 'Project scheduler not configured for assigning a task to a user.')

t = task_repo.get_task_by(project_id=a_project.id, id=int(task_id))
user_pref = t.user_pref or {}
assign_user = user_pref.get("assign_user", [])

user_email = current_user.email_addr
if user_email not in assign_user:
assign_user.append(user_email)
user_pref["assign_user"] = assign_user
t.user_pref = user_pref
flag_modified(t, "user_pref")
task_repo.update(t)
current_app.logger.info("User %s assigned to task %s", current_user.fullname, task_id)

return Response(json.dumps({'success': True}), 200, mimetype="application/json")
2 changes: 1 addition & 1 deletion pybossa/themes/default
Submodule default updated 1 files
+1 −1 static/js/pybossa
95 changes: 95 additions & 0 deletions test/test_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -9850,6 +9850,7 @@ def test_browse_task_display_info_columns_sort_priority(self):
assert "class=\" sort-asc sortable\" data-sort=\"completed_by\"" not in str(res.data), "Unexpected sorted column (sort-asc) indicator on Completed By."
assert "class=\" sort-asc sortable\" data-sort=\"priority\"" not in str(res.data), "Missing sorted column indicator (sort-asc) on Priority."


class TestWebUserMetadataUpdate(web.Helper):

original = {
Expand Down Expand Up @@ -10162,6 +10163,100 @@ def test_release_category_locks_succeed(self, release_reserve_task_lock_by_id):
assert data.get('success') is True, data
assert release_reserve_task_lock_by_id.call_count == 1, release_reserve_task_lock_by_id.call_count

@with_context
def test_assign_task_wrong_payload(self):
"""Test assign task with wrong payload"""

url = "/api/task/1/assign"

user = UserFactory.create()
self.signin_user(user)
project = ProjectFactory.create(owner=user)
_ = TaskFactory.create(project=project)

data = {'projectname': 'not_exist_project_name'}
res = self.app_post_json(url, data=data, follow_redirects=False)
data = json.loads(res.data)
assert data.get('status_code') == 400, data

@with_context
def test_assign_task_without_lock(self):
"""Test assign a task to a user without lock """

url = "/api/task/1/assign"

user = UserFactory.create()
self.signin_user(user)
project = ProjectFactory.create(
info={
'sched': 'user_pref_scheduler',
'timeout': 60 * 60,
'data_classification': dict(input_data="L4 - public",
output_data="L4 - public")
},
owner=user
)
_ = TaskFactory.create(project=project)
data = {'projectname': project.short_name}

res = self.app_post_json(url, data=data, follow_redirects=False)
data = json.loads(res.data)
assert data.get('status_code') == 403, data

@with_context
@patch('pybossa.api.fetch_lock_for_user')
def test_assign_task_failed(self, fetch_lock):
"""Test assign a task to a user failed due to schedules not allowed """

url = "/api/task/1/assign"

fetch_lock.return_value = (3600, 100000)

user = UserFactory.create()
self.signin_user(user)
project = ProjectFactory.create(
info={
'sched': 'locked',
'timeout': 60 * 60,
'data_classification': dict(input_data="L4 - public",
output_data="L4 - public")
},
owner=user
)
_ = TaskFactory.create(project=project)
data = {'projectname': project.short_name}

res = self.app_post_json(url, data=data, follow_redirects=False)
data = json.loads(res.data)
assert data.get('status_code') == 403, data

@with_context
@patch('pybossa.api.fetch_lock_for_user')
def test_assign_task_succeed(self, fetch_lock):
"""Test assign a task to a user """

url = "/api/task/1/assign"

fetch_lock.return_value = (3600, 100000)

user = UserFactory.create()
self.signin_user(user)
project = ProjectFactory.create(
info={
'sched': 'user_pref_scheduler',
'timeout': 60 * 60,
'data_classification': dict(input_data="L4 - public",
output_data="L4 - public")
},
owner=user
)
_ = TaskFactory.create(project=project)
data = {'projectname': project.short_name}

res = self.app_post_json(url, data=data, follow_redirects=False)
data = json.loads(res.data)
assert data.get('success'), data


class TestWebQuizModeUpdate(web.Helper):

Expand Down

0 comments on commit b563d02

Please sign in to comment.