REST API tests: patch tasks, post/patch issues (#4465)

Co-authored-by: Kirill Sizov <kirill.sizov@intel.com>
main
Dmitry Kalinin 4 years ago committed by GitHub
parent d42e37c714
commit dd60b2d8e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -18,13 +18,9 @@
}
],
"npm.exclude": "**/.env/**",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.linting.pycodestyleEnabled": false,
"licenser.license": "Custom",
"licenser.customHeader": "Copyright (C) @YEAR@ Intel Corporation\n\nSPDX-License-Identifier: MIT",
"files.trimTrailingWhitespace": true,
"python.pythonPath": ".env/bin/python",
"sqltools.connections": [
{
"previewLimit": 50,
@ -33,9 +29,15 @@
"database": "${workspaceFolder:cvat}/db.sqlite3"
}
],
"python.defaultInterpreterPath": "${workspaceFolder}/.env/",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.linting.pycodestyleEnabled": false,
"python.testing.pytestArgs": [
"tests"
"--rootdir","${workspaceFolder}/tests/"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
"python.testing.pytestEnabled": true,
"python.testing.pytestPath": "${workspaceFolder}/.env/bin/pytest",
"python.testing.cwd": "${workspaceFolder}/tests"
}

@ -84,7 +84,7 @@ python utils/dump_objects.py
To restore DB and data volume, please use commands below.
```console
cat assets/cvat_db/data.json | docker exec -i cvat python manage.py --format=json loaddata -
cat assets/cvat_db/data.json | docker exec -i cvat python manage.py loaddata --format=json -
cat assets/cvat_db/cvat_data.tar.bz2 | docker exec -i cvat tar --strip 3 -C /home/django/data/ -xj
```

@ -298,5 +298,293 @@
"tracks": [],
"version": 0
}
},
"task": {
"2": {
"shapes": [
{
"attributes": [],
"frame": 0,
"group": 0,
"id": 1,
"label_id": 3,
"occluded": false,
"points": [
223.39453125,
226.0751953125,
513.7663269042969,
377.9619903564453
],
"rotation": 0.0,
"source": "manual",
"type": "rectangle",
"z_order": 0
},
{
"attributes": [],
"frame": 1,
"group": 0,
"id": 2,
"label_id": 3,
"occluded": false,
"points": [
63.0791015625,
139.75390625,
132.19337349397574,
112.3867469879533,
189.71144578313397,
159.23614457831354,
191.1030120481937,
246.9048192771097,
86.73554216867524,
335.5012048192784,
32.00060240964012,
250.15180722891637
],
"rotation": 0.0,
"source": "manual",
"type": "polygon",
"z_order": 0
},
{
"attributes": [],
"frame": 1,
"group": 0,
"id": 3,
"label_id": 4,
"occluded": false,
"points": [
83.0244140625,
216.75390625,
112.24759036144678,
162.48313253012202,
167.44638554216908,
183.35662650602535,
149.35602409638705,
252.0072289156633,
84.41626506024113,
292.8265060240974,
72.81987951807241,
258.9650602409638
],
"rotation": 0.0,
"source": "manual",
"type": "polygon",
"z_order": 0
},
{
"attributes": [],
"frame": 2,
"group": 0,
"id": 4,
"label_id": 3,
"occluded": false,
"points": [
24.443359375,
107.2275390625,
84.91109877913368,
61.125083240844106,
169.4316315205324,
75.1561598224198,
226.5581576026634,
113.90865704772477,
240.5892341842391,
205.77880133185317,
210.52264150943483,
270.9230854605994
],
"rotation": 0.0,
"source": "manual",
"type": "polyline",
"z_order": 0
},
{
"attributes": [],
"frame": 22,
"group": 0,
"id": 5,
"label_id": 3,
"occluded": false,
"points": [
148.94921875,
285.6865234375,
313.515094339622,
400.32830188679145,
217.36415094339463,
585.2339622641503,
64.81698113207494,
499.25283018867776
],
"rotation": 0.0,
"source": "manual",
"type": "points",
"z_order": 0
}
],
"tags": [],
"tracks": [],
"version": 0
},
"5": {
"shapes": [
{
"attributes": [],
"frame": 0,
"group": 0,
"id": 29,
"label_id": 9,
"occluded": false,
"points": [
364.0361328125,
528.87890625,
609.5286041189956,
586.544622425632,
835.2494279176244,
360.0000000000018,
543.6247139588122,
175.4691075514893,
326.9656750572103,
192.76887871853796,
244.58581235698148,
319.63386727689067
],
"rotation": 0.0,
"source": "manual",
"type": "polygon",
"z_order": 0
}
],
"tags": [],
"tracks": [],
"version": 0
},
"6": {
"shapes": [],
"tags": [],
"tracks": [],
"version": 0
},
"7": {
"shapes": [
{
"attributes": [],
"frame": 0,
"group": 0,
"id": 27,
"label_id": 11,
"occluded": false,
"points": [
448.3779296875,
356.4892578125,
438.2558352402775,
761.3861556064112,
744.1780320366161,
319.37356979405195,
446.1288329519466,
163.03832951945333
],
"rotation": 0.0,
"source": "manual",
"type": "polygon",
"z_order": 0
}
],
"tags": [],
"tracks": [],
"version": 0
},
"8": {
"shapes": [
{
"attributes": [],
"frame": 0,
"group": 0,
"id": 30,
"label_id": 13,
"occluded": false,
"points": [
440.0439453125,
84.0791015625,
71.83311938382576,
249.81514762516053,
380.4441591784325,
526.585365853658,
677.6251604621302,
260.42875481386363,
629.4557124518615,
127.35044929396645
],
"rotation": 0.0,
"source": "manual",
"type": "polygon",
"z_order": 0
}
],
"tags": [],
"tracks": [],
"version": 0
},
"9": {
"shapes": [
{
"attributes": [],
"frame": 0,
"group": 0,
"id": 31,
"label_id": 6,
"occluded": false,
"points": [
65.6189987163034,
100.96585365853753,
142.12734274711147,
362.6243902439037
],
"rotation": 0.0,
"source": "manual",
"type": "rectangle",
"z_order": 0
}
],
"tags": [],
"tracks": [],
"version": 0
},
"11": {
"shapes": [
{
"attributes": [],
"frame": 0,
"group": 0,
"id": 33,
"label_id": 7,
"occluded": false,
"points": [
100.14453125,
246.03515625,
408.8692551505537,
327.5483359746413,
588.5839936608554,
289.0380348652925,
623.8851030110927,
183.77654516640177,
329.2812995245622,
71.45483359746322
],
"rotation": 0.0,
"source": "manual",
"type": "polyline",
"z_order": 0
}
],
"tags": [],
"tracks": [],
"version": 0
},
"12": {
"shapes": [],
"tags": [],
"tracks": [],
"version": 0
}
}
}

@ -3600,7 +3600,7 @@
"name": "task2",
"mode": "annotation",
"owner": 2,
"assignee": null,
"assignee": 7,
"bug_tracker": "",
"created_date": "2021-12-14T18:50:29.458Z",
"updated_date": "2021-12-22T07:14:15.234Z",
@ -3621,7 +3621,7 @@
"name": "task2",
"mode": "interpolation",
"owner": 2,
"assignee": null,
"assignee": 15,
"bug_tracker": "",
"created_date": "2022-02-16T06:25:48.168Z",
"updated_date": "2022-02-21T10:40:21.257Z",
@ -3684,7 +3684,7 @@
"name": "task1",
"mode": "annotation",
"owner": 2,
"assignee": null,
"assignee": 9,
"bug_tracker": "",
"created_date": "2022-03-05T08:30:48.612Z",
"updated_date": "2022-03-05T08:52:34.908Z",
@ -3705,7 +3705,7 @@
"name": "task1_in_project1",
"mode": "annotation",
"owner": 10,
"assignee": 20,
"assignee": 1,
"bug_tracker": "",
"created_date": "2022-03-05T09:33:10.420Z",
"updated_date": "2022-03-05T09:47:49.667Z",
@ -4567,7 +4567,7 @@
"pk": 11,
"fields": {
"segment": 11,
"assignee": null,
"assignee": 9,
"status": "annotation",
"stage": "annotation",
"state": "in progress"
@ -5628,5 +5628,141 @@
"user": 20,
"rating": 0.0
}
},
{
"model": "engine.issue",
"pk": 1,
"fields": {
"frame": 0,
"position": "[244.58581235698148, 319.63386727689067, 326.9656750572103, 192.76887871853796, 543.6247139588122, 175.4691075514893, 835.2494279176244, 360.0000000000018, 609.5286041189956, 586.544622425632, 364.0361328125, 528.87890625, 244.58581235698148, 319.63386727689067]",
"job": 7,
"owner": 2,
"assignee": null,
"created_date": "2022-03-16T11:04:39.444Z",
"updated_date": null,
"resolved": false
}
},
{
"model": "engine.issue",
"pk": 2,
"fields": {
"frame": 0,
"position": "[98.48046875, 696.72265625, 326.1220703125, 841.5859375]",
"job": 9,
"owner": 11,
"assignee": null,
"created_date": "2022-03-16T11:07:22.170Z",
"updated_date": null,
"resolved": false
}
},
{
"model": "engine.issue",
"pk": 3,
"fields": {
"frame": 5,
"position": "[108.1845703125, 235.0, 720.0087890625, 703.3505859375]",
"job": 16,
"owner": 11,
"assignee": null,
"created_date": "2022-03-16T11:08:18.367Z",
"updated_date": null,
"resolved": false
}
},
{
"model": "engine.issue",
"pk": 4,
"fields": {
"frame": 5,
"position": "[295.36328125, 243.6044921875, 932.23046875, 561.4921875]",
"job": 10,
"owner": 2,
"assignee": null,
"created_date": "2022-03-16T12:40:00.764Z",
"updated_date": null,
"resolved": false
}
},
{
"model": "engine.issue",
"pk": 5,
"fields": {
"frame": 0,
"position": "[65.6189987163034, 100.96585365853753, 142.12734274711147, 362.6243902439037]",
"job": 11,
"owner": 20,
"assignee": null,
"created_date": "2022-03-16T12:49:29.369Z",
"updated_date": null,
"resolved": false
}
},
{
"model": "engine.comment",
"pk": 1,
"fields": {
"issue": 1,
"owner": 2,
"message": "Why are we still here?",
"created_date": "2022-03-16T11:04:39.447Z",
"updated_date": "2022-03-16T11:04:39.447Z"
}
},
{
"model": "engine.comment",
"pk": 2,
"fields": {
"issue": 1,
"owner": 2,
"message": "Just to suffer?",
"created_date": "2022-03-16T11:04:49.821Z",
"updated_date": "2022-03-16T11:04:49.821Z"
}
},
{
"model": "engine.comment",
"pk": 3,
"fields": {
"issue": 2,
"owner": 11,
"message": "Something should be here",
"created_date": "2022-03-16T11:07:22.173Z",
"updated_date": "2022-03-16T11:07:22.173Z"
}
},
{
"model": "engine.comment",
"pk": 4,
"fields": {
"issue": 3,
"owner": 11,
"message": "Another one issue",
"created_date": "2022-03-16T11:08:18.370Z",
"updated_date": "2022-03-16T11:08:18.370Z"
}
},
{
"model": "engine.comment",
"pk": 5,
"fields": {
"issue": 4,
"owner": 2,
"message": "Issue with empty frame",
"created_date": "2022-03-16T12:40:00.767Z",
"updated_date": "2022-03-16T12:40:00.767Z"
}
},
{
"model": "engine.comment",
"pk": 6,
"fields": {
"issue": 5,
"owner": 20,
"message": "Wrong position",
"created_date": "2022-03-16T12:49:29.372Z",
"updated_date": "2022-03-16T12:49:29.372Z"
}
}
]

@ -0,0 +1,221 @@
{
"count": 5,
"next": null,
"previous": null,
"results": [
{
"assignee": null,
"comments": [
{
"created_date": "2022-03-16T12:49:29.372000Z",
"id": 6,
"issue": 5,
"message": "Wrong position",
"owner": {
"first_name": "User",
"id": 20,
"last_name": "Sixth",
"url": "http://localhost:8080/api/users/20",
"username": "user6"
},
"updated_date": "2022-03-16T12:49:29.372000Z"
}
],
"created_date": "2022-03-16T12:49:29.369000Z",
"frame": 0,
"id": 5,
"job": 11,
"owner": {
"first_name": "User",
"id": 20,
"last_name": "Sixth",
"url": "http://localhost:8080/api/users/20",
"username": "user6"
},
"position": [
65.6189987163034,
100.96585365853753,
142.12734274711147,
362.6243902439037
],
"resolved": false,
"updated_date": null
},
{
"assignee": null,
"comments": [
{
"created_date": "2022-03-16T12:40:00.767000Z",
"id": 5,
"issue": 4,
"message": "Issue with empty frame",
"owner": {
"first_name": "User",
"id": 2,
"last_name": "First",
"url": "http://localhost:8080/api/users/2",
"username": "user1"
},
"updated_date": "2022-03-16T12:40:00.767000Z"
}
],
"created_date": "2022-03-16T12:40:00.764000Z",
"frame": 5,
"id": 4,
"job": 10,
"owner": {
"first_name": "User",
"id": 2,
"last_name": "First",
"url": "http://localhost:8080/api/users/2",
"username": "user1"
},
"position": [
295.36328125,
243.6044921875,
932.23046875,
561.4921875
],
"resolved": false,
"updated_date": null
},
{
"assignee": null,
"comments": [
{
"created_date": "2022-03-16T11:08:18.370000Z",
"id": 4,
"issue": 3,
"message": "Another one issue",
"owner": {
"first_name": "Business",
"id": 11,
"last_name": "Second",
"url": "http://localhost:8080/api/users/11",
"username": "business2"
},
"updated_date": "2022-03-16T11:08:18.370000Z"
}
],
"created_date": "2022-03-16T11:08:18.367000Z",
"frame": 5,
"id": 3,
"job": 16,
"owner": {
"first_name": "Business",
"id": 11,
"last_name": "Second",
"url": "http://localhost:8080/api/users/11",
"username": "business2"
},
"position": [
108.1845703125,
235.0,
720.0087890625,
703.3505859375
],
"resolved": false,
"updated_date": null
},
{
"assignee": null,
"comments": [
{
"created_date": "2022-03-16T11:07:22.173000Z",
"id": 3,
"issue": 2,
"message": "Something should be here",
"owner": {
"first_name": "Business",
"id": 11,
"last_name": "Second",
"url": "http://localhost:8080/api/users/11",
"username": "business2"
},
"updated_date": "2022-03-16T11:07:22.173000Z"
}
],
"created_date": "2022-03-16T11:07:22.170000Z",
"frame": 0,
"id": 2,
"job": 9,
"owner": {
"first_name": "Business",
"id": 11,
"last_name": "Second",
"url": "http://localhost:8080/api/users/11",
"username": "business2"
},
"position": [
98.48046875,
696.72265625,
326.1220703125,
841.5859375
],
"resolved": false,
"updated_date": null
},
{
"assignee": null,
"comments": [
{
"created_date": "2022-03-16T11:04:39.447000Z",
"id": 1,
"issue": 1,
"message": "Why are we still here?",
"owner": {
"first_name": "User",
"id": 2,
"last_name": "First",
"url": "http://localhost:8080/api/users/2",
"username": "user1"
},
"updated_date": "2022-03-16T11:04:39.447000Z"
},
{
"created_date": "2022-03-16T11:04:49.821000Z",
"id": 2,
"issue": 1,
"message": "Just to suffer?",
"owner": {
"first_name": "User",
"id": 2,
"last_name": "First",
"url": "http://localhost:8080/api/users/2",
"username": "user1"
},
"updated_date": "2022-03-16T11:04:49.821000Z"
}
],
"created_date": "2022-03-16T11:04:39.444000Z",
"frame": 0,
"id": 1,
"job": 7,
"owner": {
"first_name": "User",
"id": 2,
"last_name": "First",
"url": "http://localhost:8080/api/users/2",
"username": "user1"
},
"position": [
244.58581235698148,
319.63386727689067,
326.9656750572103,
192.76887871853796,
543.6247139588122,
175.4691075514893,
835.2494279176244,
360.0000000000018,
609.5286041189956,
586.544622425632,
364.0361328125,
528.87890625,
244.58581235698148,
319.63386727689067
],
"resolved": false,
"updated_date": null
}
]
}

@ -173,7 +173,13 @@
"url": "http://localhost:8080/api/jobs/12"
},
{
"assignee": null,
"assignee": {
"first_name": "Worker",
"id": 9,
"last_name": "Fourth",
"url": "http://localhost:8080/api/users/9",
"username": "worker4"
},
"bug_tracker": "",
"data_chunk_size": 72,
"data_compressed_chunk_type": "imageset",

@ -110,11 +110,11 @@
},
{
"assignee": {
"first_name": "User",
"id": 20,
"last_name": "Sixth",
"url": "http://localhost:8080/api/users/20",
"username": "user6"
"first_name": "Admin",
"id": 1,
"last_name": "First",
"url": "http://localhost:8080/api/users/1",
"username": "admin1"
},
"bug_tracker": "",
"created_date": "2022-03-05T09:33:10.420000Z",
@ -169,7 +169,13 @@
{
"jobs": [
{
"assignee": null,
"assignee": {
"first_name": "Worker",
"id": 9,
"last_name": "Fourth",
"url": "http://localhost:8080/api/users/9",
"username": "worker4"
},
"id": 11,
"stage": "annotation",
"state": "in progress",
@ -230,7 +236,13 @@
"url": "http://localhost:8080/api/tasks/9"
},
{
"assignee": null,
"assignee": {
"first_name": "Worker",
"id": 9,
"last_name": "Fourth",
"url": "http://localhost:8080/api/users/9",
"username": "worker4"
},
"bug_tracker": "",
"created_date": "2022-03-05T08:30:48.612000Z",
"data": 8,
@ -416,7 +428,13 @@
"url": "http://localhost:8080/api/tasks/6"
},
{
"assignee": null,
"assignee": {
"first_name": "Dummy",
"id": 15,
"last_name": "Second",
"url": "http://localhost:8080/api/users/15",
"username": "dummy2"
},
"bug_tracker": "",
"created_date": "2022-02-16T06:25:48.168000Z",
"data": 5,
@ -476,7 +494,13 @@
"url": "http://localhost:8080/api/tasks/5"
},
{
"assignee": null,
"assignee": {
"first_name": "Worker",
"id": 7,
"last_name": "Second",
"url": "http://localhost:8080/api/users/7",
"username": "worker2"
},
"bug_tracker": "",
"created_date": "2021-12-14T18:50:29.458000Z",
"data": 2,

@ -103,6 +103,11 @@ def annotations():
with open(osp.join(ASSETS_DIR, 'annotations.json')) as f:
return json.load(f)
@pytest.fixture(scope='module')
def issues():
with open(osp.join(ASSETS_DIR, 'issues.json')) as f:
return Container(json.load(f)['results'])
@pytest.fixture(scope='module')
def users_by_name(users):
return {user['username']: user for user in users}
@ -115,6 +120,22 @@ def jobs_by_org(tasks, jobs):
data[''] = data.pop(None, [])
return data
@pytest.fixture(scope='module')
def tasks_by_org(tasks):
data = {}
for task in tasks:
data.setdefault(task['organization'], []).append(task)
data[''] = data.pop(None, [])
return data
@pytest.fixture(scope='module')
def issues_by_org(tasks, jobs, issues):
data = {}
for issue in issues:
data.setdefault(tasks[jobs[issue['job']]['task_id']]['organization'], []).append(issue)
data[''] = data.pop(None, [])
return data
@pytest.fixture(scope='module')
def assignee_id():
def get_id(data):
@ -154,6 +175,22 @@ def is_job_staff(jobs, is_task_staff, assignee_id):
is_task_staff(user_id, jobs[jid]['task_id'])
return check
@pytest.fixture(scope='module')
def is_issue_staff(issues, jobs, assignee_id):
@ownership
def check(user_id, issue_id):
return user_id == issues[issue_id]['owner']['id'] or \
user_id == assignee_id(issues[issue_id]) or \
user_id == assignee_id(jobs[issues[issue_id]['job']])
return check
@pytest.fixture(scope='module')
def is_issue_admin(issues, jobs, is_task_staff):
@ownership
def check(user_id, issue_id):
return is_task_staff(user_id, jobs[issues[issue_id]['job']]['task_id'])
return check
@pytest.fixture(scope='module')
def find_users(test_db):
def find(**kwargs):
@ -225,8 +262,36 @@ def find_job_staff_user(is_job_staff):
return None, None
return find
@pytest.fixture(scope='module')
def find_task_staff_user(is_task_staff):
def find(tasks, users, is_staff):
for task in tasks:
for user in users:
if is_staff == is_task_staff(user['id'], task['id']):
return user['username'], task['id']
return None, None
return find
@pytest.fixture(scope='module')
def find_issue_staff_user(is_issue_staff, is_issue_admin):
def find(issues, users, is_staff, is_admin):
for issue in issues:
for user in users:
i_admin, i_staff = is_issue_admin(user['id'], issue['id']), is_issue_staff(user['id'], issue['id'])
if (is_admin is None and (i_staff or i_admin) == is_staff) \
or (is_admin == i_admin and is_staff == i_staff):
return user['username'], issue['id']
return None, None
return find
@pytest.fixture(scope='module')
def filter_jobs_with_shapes(annotations):
def find(jobs):
return list(filter(lambda j: annotations['job'][str(j['id'])]['shapes'], jobs))
return find
@pytest.fixture(scope='module')
def filter_tasks_with_shapes(annotations):
def find(tasks):
return list(filter(lambda t: annotations['task'][str(t['id'])]['shapes'], tasks))
return find

@ -0,0 +1,140 @@
# Copyright (C) 2022 Intel Corporation
#
# SPDX-License-Identifier: MIT
import pytest
from http import HTTPStatus
from deepdiff import DeepDiff
from copy import deepcopy
from .utils.config import post_method, patch_method
class TestPostIssues:
def _test_check_response(self, user, data, is_allow, **kwargs):
response = post_method(user, 'issues', data, **kwargs)
if is_allow:
assert response.status_code == HTTPStatus.CREATED
assert user == response.json()['owner']['username']
assert data['message'] == response.json()['comments'][0]['message']
assert DeepDiff(data, response.json(),
exclude_regex_paths=r"root\['created_date|updated_date|comments|id|owner|message'\]") == {}
else:
assert response.status_code == HTTPStatus.FORBIDDEN
@pytest.mark.parametrize('org', [''])
@pytest.mark.parametrize('privilege, job_staff, is_allow', [
('admin', True, True), ('admin', False, True),
('business', True, True), ('business', False, False),
('worker', True, True), ('worker', False, False),
('user', True, True), ('user', False, False)
])
def test_user_create_issue(self, org, privilege, job_staff, is_allow,
find_job_staff_user, find_users, jobs_by_org):
users = find_users(privilege=privilege)
jobs = jobs_by_org[org]
username, jid = find_job_staff_user(jobs, users, job_staff)
job, = filter(lambda job: job['id'] == jid, jobs)
data = {
"assignee": None,
"comments": [],
"job": jid,
"frame": job['start_frame'],
"position": [
0., 0., 1., 1.,
],
"resolved": False,
"message": "lorem ipsum",
}
self._test_check_response(username, data, is_allow)
@pytest.mark.parametrize('org', [2])
@pytest.mark.parametrize('role, job_staff, is_allow', [
('maintainer', False, True), ('owner', False, True),
('supervisor', False, False), ('worker', False, False),
('maintainer', True, True), ('owner', True, True),
('supervisor', True, True), ('worker', True, True)
])
def test_member_create_issue(self, org, role, job_staff, is_allow,
find_job_staff_user, find_users, jobs_by_org, jobs):
users = find_users(role=role, org=org)
username, jid = find_job_staff_user(jobs_by_org[org], users, job_staff)
job = jobs[jid]
data = {
"assignee": None,
"comments": [],
"job": jid,
"frame": job['start_frame'],
"position": [
0., 0., 1., 1.,
],
"resolved": False,
"message": "lorem ipsum",
}
self._test_check_response(username, data, is_allow, org_id=org)
class TestPatchIssues:
def _test_check_response(self, user, issue_id, data, is_allow, **kwargs):
response = patch_method(user, f'issues/{issue_id}', data,
action='update', **kwargs)
if is_allow:
assert response.status_code == HTTPStatus.OK
assert DeepDiff(data, response.json(),
exclude_regex_paths=r"root\['created_date|updated_date|comments|id|owner'\]") == {}
else:
assert response.status_code == HTTPStatus.FORBIDDEN
@pytest.fixture(scope='class')
def request_data(self, issues):
def get_data(issue_id):
data = deepcopy(issues[issue_id])
data['resolved'] = not data['resolved']
data.pop('comments')
data.pop('updated_date')
data.pop('id')
data.pop('owner')
return data
return get_data
@pytest.mark.parametrize('org', [''])
@pytest.mark.parametrize('privilege, issue_staff, issue_admin, is_allow', [
('admin', True, None, True), ('admin', False, None, True),
('business', True, None, True), ('business', False, None, False),
('user', True, None, True), ('user', False, None, False),
('worker', False, True, True), ('worker', True, False, False),
('worker', False, False, False)
])
def test_user_update_issue(self, org, privilege, issue_staff, issue_admin, is_allow,
find_issue_staff_user, find_users, issues_by_org, request_data):
users = find_users(privilege=privilege)
issues = issues_by_org[org]
username, issue_id = find_issue_staff_user(issues, users, issue_staff, issue_admin)
data = request_data(issue_id)
self._test_check_response(username, issue_id, data, is_allow)
@pytest.mark.parametrize('org', [2])
@pytest.mark.parametrize('role, issue_staff, issue_admin, is_allow', [
('maintainer', True, None, True), ('maintainer', False, None, True),
('supervisor', True, None, True), ('supervisor', False, None, False),
('owner', True, None, True), ('owner', False, None, True),
('worker', False, True, True), ('worker', True, False, False),
('worker', False, False, False)
])
def test_member_update_issue(self, org, role, issue_staff, issue_admin, is_allow,
find_issue_staff_user, find_users, issues_by_org, request_data):
users = find_users(role=role, org=org)
issues = issues_by_org[org]
username, issue_id = find_issue_staff_user(issues, users, issue_staff, issue_admin)
data = request_data(issue_id)
self._test_check_response(username, issue_id, data, is_allow, org_id=org)

@ -6,7 +6,7 @@ from http import HTTPStatus
from deepdiff import DeepDiff
import pytest
from .utils.config import get_method, post_method
from .utils.config import get_method, post_method, patch_method
class TestGetTasks:
def _test_task_list_200(self, user, project_id, data, exclude_paths = '', **kwargs):
@ -155,3 +155,61 @@ class TestGetData:
response = get_method(self._USERNAME, f'tasks/{task_id}/data', type='frame', quality='original', number=0)
assert response.status_code == HTTPStatus.OK
assert response.headers['Content-Type'] == content_type
class TestPatchTaskAnnotations:
def _test_check_respone(self, is_allow, response, data=None):
if is_allow:
assert response.status_code == HTTPStatus.OK
assert DeepDiff(data, response.json(),
exclude_paths="root['version']") == {}
else:
assert response.status_code == HTTPStatus.FORBIDDEN
@pytest.fixture(scope='class')
def request_data(self, annotations):
def get_data(tid):
data = annotations['task'][str(tid)].copy()
data['shapes'][0].update({'points': [2.0, 3.0, 4.0, 5.0, 6.0, 7.0]})
data['version'] += 1
return data
return get_data
@pytest.mark.parametrize('org', [''])
@pytest.mark.parametrize('privilege, task_staff, is_allow', [
('admin', True, True), ('admin', False, True),
('business', True, True), ('business', False, False),
('worker', True, True), ('worker', False, False),
('user', True, True), ('user', False, False)
])
def test_user_update_task_annotations(self, org, privilege, task_staff, is_allow,
find_task_staff_user, find_users, request_data, tasks_by_org, filter_tasks_with_shapes):
users = find_users(privilege=privilege)
tasks = tasks_by_org[org]
filtered_tasks = filter_tasks_with_shapes(tasks)
username, tid = find_task_staff_user(filtered_tasks, users, task_staff)
data = request_data(tid)
response = patch_method(username, f'tasks/{tid}/annotations', data,
org_id=org, action='update')
self._test_check_respone(is_allow, response, data)
@pytest.mark.parametrize('org', [2])
@pytest.mark.parametrize('role, task_staff, is_allow', [
('maintainer', False, True), ('owner', False, True),
('supervisor', False, False), ('worker', False, False),
('maintainer', True, True), ('owner', True, True),
('supervisor', True, True), ('worker', True, True)
])
def test_member_update_task_annotation(self, org, role, task_staff, is_allow,
find_task_staff_user, find_users, tasks_by_org, request_data):
users = find_users(role=role, org=org)
tasks = tasks_by_org[org]
username, tid = find_task_staff_user(tasks, users, task_staff)
data = request_data(tid)
response = patch_method(username, f'tasks/{tid}/annotations', data,
org_id=org, action='update')
self._test_check_respone(is_allow, response, data)

@ -4,17 +4,17 @@ import json
annotations = {}
for obj in ['user', 'project', 'task', 'job', 'organization', 'membership',
'invitation']:
'invitation', 'issue']:
response = get_method('admin1', f'{obj}s', page_size='all')
with open(osp.join(ASSETS_DIR, f'{obj}s.json'), 'w') as f:
json.dump(response.json(), f, indent=2, sort_keys=True)
if obj == 'job':
if obj in ['job', 'task']:
annotations[obj] = {}
for job in response.json()['results']:
jid = job["id"]
response = get_method('admin1', f'jobs/{jid}/annotations')
annotations[obj][jid] = response.json()
for _obj in response.json()['results']:
oid = _obj["id"]
response = get_method('admin1', f'{obj}s/{oid}/annotations')
annotations[obj][oid] = response.json()
with open(osp.join(ASSETS_DIR, f'annotations.json'), 'w') as f:
json.dump(annotations, f, indent=2, sort_keys=True)

Loading…
Cancel
Save