Skip to content

Commit 1c20338

Browse files
Narek MkhitaryanNarek Mkhitaryan
authored andcommitted
updated custom_workflow test setup
1 parent a8f3c51 commit 1c20338

File tree

6 files changed

+165
-6
lines changed

6 files changed

+165
-6
lines changed

src/superannotate/lib/core/entities/project.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ class TeamEntity(BaseModel):
163163
users: Optional[List[UserEntity]]
164164
pending_invitations: Optional[List[Any]]
165165
creator_id: Optional[str]
166+
owner_id: Optional[str]
166167

167168
class Config:
168169
extra = Extra.ignore

src/superannotate/lib/infrastructure/controller.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,10 @@ def __init__(self, config: ConfigEntity):
909909
self.subsets = SubsetManager(self.service_provider)
910910
self.integrations = IntegrationManager(self.service_provider)
911911

912+
@property
913+
def org_id(self):
914+
return self._team.owner_id
915+
912916
@property
913917
def current_user(self):
914918
return self._user

src/superannotate/lib/infrastructure/serviceprovider.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import base64
12
import datetime
23
from typing import List
34

@@ -36,6 +37,7 @@ class ServiceProvider(BaseServiceProvider):
3637
URL_FOLDERS_IMAGES = "images-folders"
3738
URL_INVITE_CONTRIBUTORS = "api/v1/team/{}/inviteUsers"
3839
URL_ANNOTATION_UPLOAD_PATH_TOKEN = "images/getAnnotationsPathsAndTokens"
40+
URL_CREATE_WORKFLOW = "api/v1/workflows/submit"
3941

4042
def __init__(self, client: HttpClient):
4143
self.enum_mapping = {"approval_status": ApprovalStatus.get_mapping()}
@@ -254,3 +256,17 @@ def invite_contributors(self, team_id: int, team_role: int, emails: List[str]):
254256
"post",
255257
data=dict(emails=emails, team_role=team_role),
256258
)
259+
260+
def create_custom_workflow(self, org_id: str, data: dict):
261+
return self.client.request(
262+
url=self.URL_CREATE_WORKFLOW,
263+
method="post",
264+
headers={
265+
"x-sa-entity-context": base64.b64encode(
266+
f'{{"team_id":{self.client.team_id},"organization_id":"{org_id}"}}'.encode(
267+
"utf-8"
268+
)
269+
).decode()
270+
},
271+
data=data,
272+
)

src/superannotate/lib/infrastructure/services/work_management.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class WorkManagementService(BaseWorkManagementService):
1313
URL_LIST = "workflows"
1414
URL_LIST_STATUSES = "workflows/{workflow_id}/workflowstatuses"
1515
URL_LIST_ROLES = "workflows/{workflow_id}/workflowroles"
16+
URL_CREATE_ROLE = "roles"
17+
URL_CREATE_STATUS = "statuses"
1618

1719
def get_workflow(self, pk: int) -> WorkflowEntity:
1820
response = self.list_workflows(Filter("id", pk, OperatorEnum.EQ))
@@ -65,3 +67,31 @@ def list_workflow_roles(self, project_id: int, workflow_id: int):
6567
"join": "role",
6668
},
6769
)
70+
71+
def create_custom_role(self, org_id: str, data: dict):
72+
return self.client.request(
73+
url=self.URL_CREATE_ROLE,
74+
method="post",
75+
headers={
76+
"x-sa-entity-context": base64.b64encode(
77+
f'{{"team_id":{self.client.team_id},"organization_id":"{org_id}"}}'.encode(
78+
"utf-8"
79+
)
80+
).decode()
81+
},
82+
data=data,
83+
)
84+
85+
def create_custom_status(self, org_id: str, data: dict):
86+
return self.client.request(
87+
url=self.URL_CREATE_STATUS,
88+
method="post",
89+
headers={
90+
"x-sa-entity-context": base64.b64encode(
91+
f'{{"team_id":{self.client.team_id},"organization_id":"{org_id}"}}'.encode(
92+
"utf-8"
93+
)
94+
).decode()
95+
},
96+
data=data,
97+
)

tests/applicatoin/custom_workflow.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import contextvars
2+
import json
23
import os
34
import re
45
import time
@@ -24,9 +25,39 @@ class TestWorkflow(TestCase):
2425
CLASSES_PATH = "sample_project_vector/classes/classes.json"
2526
ANNOTATIONS_PATH = "sample_project_vector"
2627
PROJECT_TYPE = "Vector"
28+
CUSTOM_WORKFLOW = "application/custom_workflow_payload.json"
2729

2830
@classmethod
2931
def setUpClass(cls, *args, **kwargs):
32+
33+
# setup custom role
34+
sa.controller.service_provider.work_management.create_custom_role(
35+
org_id=sa.controller.org_id,
36+
data={
37+
"name": "CustomRole",
38+
"description": "Test custom role",
39+
"rolePermissions": [{"permission_id": 11}, {"permission_id": 12}],
40+
},
41+
)
42+
43+
# setup custom status
44+
sa.controller.service_provider.work_management.create_custom_status(
45+
org_id=sa.controller.org_id,
46+
data={
47+
"name": "CustomStatus",
48+
"icon_id": 7,
49+
"shortcut_id": 7,
50+
"description": "test status",
51+
},
52+
)
53+
54+
# setup custom workflow
55+
with open(os.path.join(DATA_SET_PATH, cls.CUSTOM_WORKFLOW)) as f:
56+
sa.controller.service_provider.create_custom_workflow(
57+
org_id=sa.controller.org_id,
58+
data=json.load(f),
59+
)
60+
3061
cls.tearDownClass()
3162
cls._project = sa.create_project(
3263
cls.PROJECT_NAME, cls.PROJECT_DESCRIPTION, cls.PROJECT_TYPE, workflow="ttp"
@@ -37,12 +68,9 @@ def tearDownClass(cls) -> None:
3768
try:
3869
projects = sa.search_projects(cls.PROJECT_NAME, return_metadata=True)
3970
for project in projects:
40-
try:
41-
sa.delete_project(project)
42-
except Exception as e:
43-
print(str(e))
44-
except Exception as e:
45-
print(str(e))
71+
sa.delete_project(project)
72+
except Exception:
73+
pass
4674

4775
@property
4876
def classes_path(self):
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{
2+
"name": "ttp",
3+
"description": "mock workflow for test",
4+
"raw_config": {
5+
"roles": [
6+
"Annotator",
7+
"QA",
8+
"CustomRole"
9+
],
10+
"statuses": [
11+
"NotStarted",
12+
"QualityCheck",
13+
"Returned",
14+
"Skipped",
15+
"Completed",
16+
"CustomStatus"
17+
],
18+
"transitions": [
19+
{
20+
"to": "QualityCheck",
21+
"from": "NotStarted",
22+
"name": "move to in progress",
23+
"allowed_roles": [
24+
"Annotator"
25+
]
26+
},
27+
{
28+
"to": "QualityCheck",
29+
"from": "Returned",
30+
"name": "move to quality check",
31+
"allowed_roles": [
32+
"Annotator",
33+
"QA"
34+
]
35+
},
36+
{
37+
"to": "Returned",
38+
"from": "QualityCheck",
39+
"name": "move back to in progress",
40+
"allowed_roles": [
41+
"Annotator",
42+
"QA"
43+
]
44+
},
45+
{
46+
"to": "Completed",
47+
"from": "QualityCheck",
48+
"name": "move to completed",
49+
"allowed_roles": [
50+
"QA"
51+
]
52+
}
53+
],
54+
"start_status": "Returned",
55+
"allowed_resources_to_roles": {
56+
"QA": {
57+
"view_items": {
58+
"statuses": [
59+
"QualityCheck"
60+
]
61+
}
62+
},
63+
"Annotator": {
64+
"view_items": {
65+
"statuses": [
66+
"NotStarted",
67+
"Returned"
68+
]
69+
}
70+
},
71+
"CustomRole": {
72+
"view_items": {
73+
"statuses": [
74+
"CustomStatus"
75+
]
76+
}
77+
}
78+
}
79+
}
80+
}

0 commit comments

Comments
 (0)