Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Kontr 2.0
Portal API Backend
Commits
bf102b33
Verified
Commit
bf102b33
authored
Oct 01, 2018
by
Peter Stanko
Browse files
Submission create check - test + fixes
parent
a6bd7ff8
Pipeline
#14175
failed with stage
in 7 minutes and 58 seconds
Changes
21
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
management/data/__init__.py
View file @
bf102b33
...
@@ -107,10 +107,9 @@ class DataManagement(object):
...
@@ -107,10 +107,9 @@ class DataManagement(object):
course
=
self
.
rest
.
find
.
course
(
course
)
course
=
self
.
rest
.
find
.
course
(
course
)
role
=
self
.
creator
.
scaffold_project
(
course
,
name
)
role
=
self
.
creator
.
scaffold_project
(
course
,
name
)
self
.
db
.
session
.
commit
()
self
.
db
.
session
.
commit
()
log
.
debug
(
f
'[DATA] Created ro
le
:
{
role
.
log_name
}
'
)
log
.
debug
(
f
'[DATA] Created
p
ro
ject
:
{
role
.
log_name
}
'
)
return
role
return
role
def
create_role
(
self
,
course_name
:
str
,
role_type
:
str
,
name
:
str
)
->
Role
:
def
create_role
(
self
,
course_name
:
str
,
role_type
:
str
,
name
:
str
)
->
Role
:
"""Creates role in the course based on type
"""Creates role in the course based on type
Args:
Args:
...
...
management/data/shared.py
View file @
bf102b33
...
@@ -4,12 +4,14 @@ Factory to create sample data
...
@@ -4,12 +4,14 @@ Factory to create sample data
import
random
import
random
import
string
import
string
from
datetime
import
timedelta
from
flask_sqlalchemy
import
SQLAlchemy
from
flask_sqlalchemy
import
SQLAlchemy
from
portal
import
logger
from
portal
import
logger
from
portal.database.models
import
Course
,
Group
,
Project
,
ReviewItem
,
Role
,
Submission
,
User
,
\
from
portal.database.models
import
Course
,
Group
,
Project
,
ReviewItem
,
Role
,
Submission
,
User
,
\
Worker
Worker
from
portal.tools
import
time
log
=
logger
.
get_logger
(
__name__
)
log
=
logger
.
get_logger
(
__name__
)
...
@@ -176,5 +178,18 @@ class DataFactory(object):
...
@@ -176,5 +178,18 @@ class DataFactory(object):
permissions
=
permissions
)
permissions
=
permissions
)
return
role
return
role
def
scaffold_project
(
self
,
course
,
name
):
def
scaffold_project
(
self
,
course
:
Course
,
name
:
str
):
return
self
.
create_project
(
course
=
course
,
name
=
name
,
codename
=
name
)
project_config
=
dict
(
file_whitelist
=
"*.*"
,
test_files_source
=
'https://gitlab.fi.muni.cz/grp-kontr2/testing/hello-test-files'
,
test_files_subdir
=
''
,
pre_submit_script
=
"python for kontr pre"
,
post_submit_script
=
"python for kontr post"
,
submission_scheduler_config
=
"python for sub Q"
,
submission_parameters
=
"{
\"
type
\"
:
\"
text
\"
}"
,
submissions_allowed_from
=
time
.
current_time
()
-
timedelta
(
days
=
1
),
submissions_allowed_to
=
time
.
current_time
()
+
timedelta
(
days
=
10
),
archive_from
=
time
.
current_time
()
+
timedelta
(
days
=
30
)
)
return
self
.
create_project
(
course
=
course
,
name
=
name
,
config
=
project_config
)
portal/database/mixins.py
View file @
bf102b33
"""
"""
A collection of Mixins specifying common behaviour and attributes of database entities.
A collection of Mixins specifying common behaviour and attributes of database entities.
"""
"""
import
datetime
from
sqlalchemy.ext.hybrid
import
hybrid_property
from
sqlalchemy.ext.hybrid
import
hybrid_property
from
portal
import
db
from
portal
import
db
...
...
portal/rest/projects.py
View file @
bf102b33
...
@@ -3,6 +3,7 @@ from flask_jwt_extended import jwt_required
...
@@ -3,6 +3,7 @@ from flask_jwt_extended import jwt_required
from
flask_restplus
import
Namespace
from
flask_restplus
import
Namespace
from
portal
import
logger
from
portal
import
logger
from
portal.database.models
import
ClientType
from
portal.rest
import
rest_helpers
from
portal.rest
import
rest_helpers
from
portal.rest.custom_resource
import
CustomResource
from
portal.rest.custom_resource
import
CustomResource
from
portal.rest.schemas
import
SCHEMAS
from
portal.rest.schemas
import
SCHEMAS
...
@@ -170,7 +171,10 @@ class ProjectSubmissions(CustomResource):
...
@@ -170,7 +171,10 @@ class ProjectSubmissions(CustomResource):
# check if a new submission can be created by this user in this project
# check if a new submission can be created by this user in this project
project
=
self
.
find
.
project
(
course
,
pid
)
project
=
self
.
find
.
project
(
course
,
pid
)
self
.
rest
.
projects
(
project
).
check_submission_create
(
client
=
user
)
if
client
.
type
==
ClientType
.
USER
:
client_instance
=
self
.
find
.
user
(
client
.
id
)
if
not
client_instance
.
is_admin
:
self
.
rest
.
projects
(
project
).
check_submission_create
(
client
=
user
)
data
=
rest_helpers
.
parse_request_data
(
data
=
rest_helpers
.
parse_request_data
(
schema
=
SCHEMAS
.
submission_create
,
action
=
'create'
,
resource
=
'submission'
schema
=
SCHEMAS
.
submission_create
,
action
=
'create'
,
resource
=
'submission'
...
@@ -179,11 +183,7 @@ class ProjectSubmissions(CustomResource):
...
@@ -179,11 +183,7 @@ class ProjectSubmissions(CustomResource):
# data for Kontr processing
# data for Kontr processing
service
=
self
.
rest
.
submissions
()
service
=
self
.
rest
.
submissions
()
new_submission
=
service
.
create_submission
(
new_submission
=
service
.
create
(
user
=
user
,
project
=
project
,
submission_params
=
data
)
user
=
user
,
project
=
project
,
submission_params
=
data
)
return
SCHEMAS
.
dump
(
'submission'
,
new_submission
),
201
return
SCHEMAS
.
dump
(
'submission'
,
new_submission
),
201
...
@@ -201,7 +201,3 @@ class ProjectTestFiles(CustomResource):
...
@@ -201,7 +201,3 @@ class ProjectTestFiles(CustomResource):
service
=
self
.
rest
.
storage
(
project
=
project
)
service
=
self
.
rest
.
storage
(
project
=
project
)
storage_entity
=
service
.
get_test_files_entity_from_storage
()
storage_entity
=
service
.
get_test_files_entity_from_storage
()
return
service
.
send_file_or_zip
(
storage_entity
)
return
service
.
send_file_or_zip
(
storage_entity
)
portal/service/errors.py
View file @
bf102b33
...
@@ -4,6 +4,8 @@ Errors in the service layer
...
@@ -4,6 +4,8 @@ Errors in the service layer
import
json
import
json
from
typing
import
Union
from
typing
import
Union
from
portal.database
import
Project
,
User
class
PortalError
(
Exception
):
class
PortalError
(
Exception
):
"""Base exception class
"""Base exception class
...
@@ -96,7 +98,7 @@ class ResourceNotFoundError(PortalAPIError):
...
@@ -96,7 +98,7 @@ class ResourceNotFoundError(PortalAPIError):
class
UnauthorizedError
(
PortalAPIError
):
class
UnauthorizedError
(
PortalAPIError
):
def
__init__
(
self
,
note
=
None
):
def
__init__
(
self
,
note
=
None
):
message
=
dict
(
message
=
f
"You are not authorized."
,)
message
=
dict
(
message
=
f
"You are not authorized."
,
)
if
note
:
if
note
:
message
[
'note'
]
=
note
message
[
'note'
]
=
note
...
@@ -144,3 +146,12 @@ class SubmissionRefusedError(PortalAPIError):
...
@@ -144,3 +146,12 @@ class SubmissionRefusedError(PortalAPIError):
class
WorkerNotAvailable
(
PortalError
):
class
WorkerNotAvailable
(
PortalError
):
def
__init__
(
self
,
message
:
str
=
None
):
def
__init__
(
self
,
message
:
str
=
None
):
self
.
message
=
message
or
"Worker is not available"
self
.
message
=
message
or
"Worker is not available"
class
SubmissionDiffTimeError
(
PortalAPIError
):
def
__init__
(
self
,
project
:
Project
,
diff_time
,
user
:
User
=
None
):
log_user
=
f
'by
{
user
.
log_name
}
'
if
user
else
''
message
=
f
"Submission cannot be created for
{
project
.
log_name
}
,
{
log_user
}
"
\
f
"you can create submission in
{
diff_time
}
."
super
().
__init__
(
code
=
429
,
message
=
message
)
portal/service/projects.py
View file @
bf102b33
"""
"""
Projects service
Projects service
"""
"""
import
datetime
import
logging
import
logging
from
datetime
import
timedelta
from
typing
import
List
from
typing
import
List
from
flask_sqlalchemy
import
BaseQuery
from
flask_sqlalchemy
import
BaseQuery
from
portal
import
storage
from
portal.async_celery
import
tasks
from
portal.async_celery
import
tasks
from
portal.database.models
import
ClientType
,
Course
,
Project
,
ProjectConfig
,
ProjectState
,
\
from
portal.database.models
import
ClientType
,
Course
,
Project
,
ProjectConfig
,
ProjectState
,
\
Submission
,
SubmissionState
,
User
Submission
,
SubmissionState
,
User
...
@@ -14,7 +16,6 @@ from portal.service import errors, filters
...
@@ -14,7 +16,6 @@ from portal.service import errors, filters
from
portal.service.errors
import
ForbiddenError
from
portal.service.errors
import
ForbiddenError
from
portal.service.general
import
GeneralService
,
get_new_name
from
portal.service.general
import
GeneralService
,
get_new_name
from
portal.tools
import
time
from
portal.tools
import
time
from
portal
import
storage
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
...
@@ -130,16 +131,40 @@ class ProjectService(GeneralService):
...
@@ -130,16 +131,40 @@ class ProjectService(GeneralService):
def
check_submission_create
(
self
,
client
=
None
):
def
check_submission_create
(
self
,
client
=
None
):
client
=
client
or
self
.
client
client
=
client
or
self
.
client
if
client
.
type
==
ClientType
.
USER
:
if
client
.
type
!=
ClientType
.
USER
:
user
=
self
.
find
.
user
(
client
.
id
)
raise
errors
.
SubmissionRefusedError
(
f
"Worker cannot create submission."
)
# TODO: Might be good to add check whether it is in DEBUG Mode
user
=
self
.
find
.
user
(
client
.
id
)
if
user
.
is_admin
:
# TODO: Might be good to add check whether it is in DEBUG Mode
return
True
if
user
.
is_admin
:
return
True
if
self
.
project
.
state
(
timestamp
=
time
.
current_time
())
!=
ProjectState
.
ACTIVE
:
if
self
.
project
.
state
(
timestamp
=
time
.
current_time
())
!=
ProjectState
.
ACTIVE
:
raise
errors
.
SubmissionRefusedError
(
f
"Project
{
self
.
project
.
name
}
not active."
)
raise
errors
.
SubmissionRefusedError
(
f
"Project
{
self
.
project
.
log_
name
}
not active."
)
if
not
ProjectService
(
self
.
project
).
can_create_submission
(
client
):
if
not
ProjectService
(
self
.
project
).
can_create_submission
(
client
):
raise
errors
.
SubmissionRefusedError
(
raise
errors
.
SubmissionRefusedError
(
f
"Submission in project
{
self
.
project
.
name
}
already active."
)
f
"Submission in project
{
self
.
project
.
log_name
}
already active."
)
self
.
_check_latest_submission
(
user
)
return
True
def
_check_latest_submission
(
self
,
user
:
User
):
latest_submission
=
self
.
get_latest_submission
(
user
)
if
not
latest_submission
:
return
True
latest_time
=
latest_submission
.
created_at
now_time
=
datetime
.
datetime
.
utcnow
()
diff_time
=
now_time
-
latest_time
delta
=
timedelta
(
minutes
=
30
)
# TODO this should be configurable @mdujava
log
.
info
(
f
"Submission for project
{
self
.
project
.
log_name
}
by user
{
user
.
log_name
}
,"
f
" time delta:
{
diff_time
}
<
{
delta
}
=
{
diff_time
<
delta
}
"
)
if
diff_time
<
delta
:
log
.
debug
(
f
"Submission for
{
self
.
project
.
log_name
}
by
{
user
.
log_name
}
"
f
"rejected based on the time delta:
{
diff_time
}
"
)
raise
errors
.
SubmissionDiffTimeError
(
self
.
project
,
diff_time
,
user
=
user
)
return
True
def
get_latest_submission
(
self
,
user
)
->
Submission
:
return
Submission
.
query
.
filter
((
Submission
.
user
==
user
)
&
(
Submission
.
project
==
self
.
project
))
\
.
order_by
(
Submission
.
created_at
.
desc
()).
first
()
def
find_all
(
self
,
course
:
Course
)
->
list
:
def
find_all
(
self
,
course
:
Course
)
->
list
:
"""List of all projects
"""List of all projects
...
@@ -154,7 +179,8 @@ class ProjectService(GeneralService):
...
@@ -154,7 +179,8 @@ class ProjectService(GeneralService):
return
filters
.
filter_projects_from_course
(
course
=
course
,
user
=
perm_service
.
client
)
return
filters
.
filter_projects_from_course
(
course
=
course
,
user
=
perm_service
.
client
)
raise
ForbiddenError
(
perm_service
.
client
)
raise
ForbiddenError
(
perm_service
.
client
)
def
update_project_test_files
(
self
):
""" Sends a request to Storage to update the project's test_files to the newest version.
def
update_project_test_files
(
self
):
"""
""" Sends a request to Storage to update the project's test_files to the newest version.
tasks
.
update_project_test_files
.
delay
(
self
.
project
.
course
.
id
,
self
.
project
.
id
)
"""
\ No newline at end of file
tasks
.
update_project_test_files
.
delay
(
self
.
project
.
course
.
id
,
self
.
project
.
id
)
portal/service/submissions.py
View file @
bf102b33
...
@@ -3,7 +3,6 @@ Submissions service
...
@@ -3,7 +3,6 @@ Submissions service
"""
"""
import
logging
import
logging
import
time
from
pathlib
import
Path
from
pathlib
import
Path
from
typing
import
List
,
Union
from
typing
import
List
,
Union
...
@@ -50,7 +49,7 @@ class SubmissionsService(GeneralService):
...
@@ -50,7 +49,7 @@ class SubmissionsService(GeneralService):
allowed
=
[]
allowed
=
[]
return
self
.
update_entity
(
entity
,
data
,
allowed
=
allowed
)
return
self
.
update_entity
(
entity
,
data
,
allowed
=
allowed
)
def
create
_submission
(
self
,
user
:
User
,
project
:
Project
,
submission_params
:
dict
):
def
create
(
self
,
user
:
User
,
project
:
Project
,
submission_params
:
dict
):
"""Creates a new submission in the database and downloads its files.
"""Creates a new submission in the database and downloads its files.
Zip and git sources are processed differently.
Zip and git sources are processed differently.
...
...
tests/rest/
uti
ls.py
→
tests/rest/
rest_too
ls.py
View file @
bf102b33
import
json
import
json
import
json
as
json_parser
from
datetime
import
datetime
from
datetime
import
datetime
import
flask
from
flask
import
Response
from
flask
import
Response
from
flask.testing
import
FlaskClient
from
flask.testing
import
FlaskClient
...
@@ -8,11 +10,24 @@ from portal import logger
...
@@ -8,11 +10,24 @@ from portal import logger
from
portal.database.models
import
Course
,
Group
,
Project
,
ProjectConfig
,
Review
,
ReviewItem
,
Role
,
\
from
portal.database.models
import
Course
,
Group
,
Project
,
ProjectConfig
,
Review
,
ReviewItem
,
Role
,
\
Submission
,
User
,
Worker
Submission
,
User
,
Worker
DEFAULT_USER_CREDENTIALS
=
json
.
dumps
({
"type"
:
"username_password"
,
def
get_user_credentials
(
username
,
password
=
'123456'
):
"identifier"
:
"admin"
,
return
json
.
dumps
({
"secret"
:
"789789"
"type"
:
"username_password"
,
})
"identifier"
:
username
,
"secret"
:
password
})
def
get_user_secret
(
username
,
secret
):
return
json
.
dumps
({
"type"
:
"secret"
,
"identifier"
:
username
,
"secret"
:
secret
})
DEFAULT_USER_CREDENTIALS
=
get_user_credentials
(
'admin'
,
'789789'
)
log
=
logger
.
get_logger
(
__name__
)
log
=
logger
.
get_logger
(
__name__
)
...
@@ -26,7 +41,8 @@ def extract_data(response: Response) -> dict:
...
@@ -26,7 +41,8 @@ def extract_data(response: Response) -> dict:
def
make_request
(
client
:
FlaskClient
,
url
:
str
,
method
:
str
=
'get'
,
def
make_request
(
client
:
FlaskClient
,
url
:
str
,
method
:
str
=
'get'
,
credentials
:
str
=
None
,
headers
:
dict
=
None
,
data
:
str
=
None
)
->
Response
:
credentials
:
str
=
None
,
headers
:
dict
=
None
,
data
:
str
=
None
,
json
:
dict
=
None
)
->
Response
:
""" Creates an authenticated request to an endpoint.
""" Creates an authenticated request to an endpoint.
Args:
Args:
...
@@ -47,6 +63,8 @@ def make_request(client: FlaskClient, url: str, method: str = 'get',
...
@@ -47,6 +63,8 @@ def make_request(client: FlaskClient, url: str, method: str = 'get',
full_url
=
API_PREFIX
+
url
full_url
=
API_PREFIX
+
url
log
.
debug
(
f
"[REQ] (
{
method
}
) -
\"
{
full_url
}
\"
"
)
log
.
debug
(
f
"[REQ] (
{
method
}
) -
\"
{
full_url
}
\"
"
)
request_method
=
getattr
(
client
,
method
)
request_method
=
getattr
(
client
,
method
)
if
json
is
not
None
and
data
is
None
:
data
=
json_parser
.
dumps
(
json
)
return
request_method
(
full_url
,
headers
=
headers
,
return
request_method
(
full_url
,
headers
=
headers
,
data
=
data
,
follow_redirects
=
True
)
data
=
data
,
follow_redirects
=
True
)
...
@@ -55,6 +73,7 @@ def __get_access_token(client, credentials):
...
@@ -55,6 +73,7 @@ def __get_access_token(client, credentials):
log
.
debug
(
f
"[REQ] Login credentials:
{
credentials
}
"
)
log
.
debug
(
f
"[REQ] Login credentials:
{
credentials
}
"
)
login_resp
=
client
.
post
(
f
"
{
API_PREFIX
}
/auth/login"
,
data
=
credentials
,
login_resp
=
client
.
post
(
f
"
{
API_PREFIX
}
/auth/login"
,
data
=
credentials
,
headers
=
{
"content-type"
:
"application/json"
})
headers
=
{
"content-type"
:
"application/json"
})
log
.
debug
(
f
"[RESP]
{
login_resp
}
"
)
resp_data
=
json
.
loads
(
str
(
login_resp
.
get_data
().
decode
(
"utf-8"
)))
resp_data
=
json
.
loads
(
str
(
login_resp
.
get_data
().
decode
(
"utf-8"
)))
return
resp_data
[
'access_token'
]
return
resp_data
[
'access_token'
]
...
@@ -259,3 +278,8 @@ class DateTimeEncoder(json.JSONEncoder):
...
@@ -259,3 +278,8 @@ class DateTimeEncoder(json.JSONEncoder):
return
o
.
isoformat
()
return
o
.
isoformat
()
return
json
.
JSONEncoder
.
default
(
self
,
o
)
return
json
.
JSONEncoder
.
default
(
self
,
o
)
def
assert_response
(
response
:
flask
.
Response
,
code
=
200
,
content_type
=
'application/json'
):
assert
response
.
status_code
==
code
assert
response
.
mimetype
==
content_type
tests/rest/test_clients.py
View file @
bf102b33
...
@@ -3,7 +3,7 @@ import json
...
@@ -3,7 +3,7 @@ import json
import
pytest
import
pytest
from
portal.database.models
import
Client
,
Secret
from
portal.database.models
import
Client
,
Secret
from
tests.rest
import
uti
ls
from
tests.rest
import
rest_too
ls
@
pytest
.
fixture
@
pytest
.
fixture
...
@@ -26,7 +26,7 @@ def worker_credentials():
...
@@ -26,7 +26,7 @@ def worker_credentials():
def
test_client_detail_using_student_cred
(
client
,
student_credentials
):
def
test_client_detail_using_student_cred
(
client
,
student_credentials
):
path
=
f
'/client'
path
=
f
'/client'
response
=
uti
ls
.
make_request
(
response
=
rest_too
ls
.
make_request
(
client
,
path
,
'get'
,
credentials
=
student_credentials
)
client
,
path
,
'get'
,
credentials
=
student_credentials
)
assert
response
.
status_code
==
200
assert
response
.
status_code
==
200
assert
response
.
mimetype
==
'application/json'
assert
response
.
mimetype
==
'application/json'
...
@@ -37,7 +37,7 @@ def test_client_detail_using_student_cred(client, student_credentials):
...
@@ -37,7 +37,7 @@ def test_client_detail_using_student_cred(client, student_credentials):
def
test_client_detail_using_executor_cred
(
client
,
worker_credentials
):
def
test_client_detail_using_executor_cred
(
client
,
worker_credentials
):
path
=
f
'/client'
path
=
f
'/client'
response
=
uti
ls
.
make_request
(
response
=
rest_too
ls
.
make_request
(
client
,
path
,
'get'
,
credentials
=
worker_credentials
)
client
,
path
,
'get'
,
credentials
=
worker_credentials
)
assert
response
.
status_code
==
200
assert
response
.
status_code
==
200
assert
response
.
mimetype
==
'application/json'
assert
response
.
mimetype
==
'application/json'
...
@@ -49,10 +49,10 @@ def test_client_detail_using_executor_cred(client, worker_credentials):
...
@@ -49,10 +49,10 @@ def test_client_detail_using_executor_cred(client, worker_credentials):
def
test_create_secret
(
client
):
def
test_create_secret
(
client
):
instance
=
Client
.
query
.
filter_by
(
codename
=
"executor"
).
first
()
instance
=
Client
.
query
.
filter_by
(
codename
=
"executor"
).
first
()
request_dict
=
dict
(
name
=
"new_secret"
)
request_dict
=
dict
(
name
=
"new_secret"
)
response
=
uti
ls
.
make_request
(
client
,
f
'/clients/
{
instance
.
id
}
/secrets'
,
response
=
rest_too
ls
.
make_request
(
client
,
f
'/clients/
{
instance
.
id
}
/secrets'
,
headers
=
{
"content-type"
:
"application/json"
},
headers
=
{
"content-type"
:
"application/json"
},
data
=
json
.
dumps
(
request_dict
),
data
=
json
.
dumps
(
request_dict
),
method
=
'post'
)
method
=
'post'
)
assert
response
.
status_code
==
201
assert
response
.
status_code
==
201
assert
response
.
mimetype
==
'application/json'
assert
response
.
mimetype
==
'application/json'
...
@@ -67,22 +67,22 @@ def test_create_secret(client):
...
@@ -67,22 +67,22 @@ def test_create_secret(client):
def
test_list_secret
(
client
):
def
test_list_secret
(
client
):
instance
=
Client
.
query
.
filter_by
(
codename
=
"executor"
).
first
()
instance
=
Client
.
query
.
filter_by
(
codename
=
"executor"
).
first
()
response
=
uti
ls
.
make_request
(
client
,
f
'/clients/
{
instance
.
id
}
/secrets'
,
response
=
rest_too
ls
.
make_request
(
client
,
f
'/clients/
{
instance
.
id
}
/secrets'
,
headers
=
{
"content-type"
:
"application/json"
},
headers
=
{
"content-type"
:
"application/json"
},
method
=
'get'
)
method
=
'get'
)
assert
response
.
status_code
==
200
assert
response
.
status_code
==
200
assert
response
.
mimetype
==
'application/json'
assert
response
.
mimetype
==
'application/json'
secrets
=
uti
ls
.
extract_data
(
response
)
secrets
=
rest_too
ls
.
extract_data
(
response
)
assert
len
(
secrets
)
==
1
assert
len
(
secrets
)
==
1
def
test_delete_secret
(
client
):
def
test_delete_secret
(
client
):
worker
=
Client
.
query
.
filter_by
(
codename
=
"executor"
).
first
()
worker
=
Client
.
query
.
filter_by
(
codename
=
"executor"
).
first
()
secret
=
Secret
.
query
.
filter_by
(
client
=
worker
).
first
()
secret
=
Secret
.
query
.
filter_by
(
client
=
worker
).
first
()
response
=
uti
ls
.
make_request
(
client
,
f
'/clients/
{
worker
.
id
}
/secrets/
{
secret
.
id
}
'
,
response
=
rest_too
ls
.
make_request
(
client
,
f
'/clients/
{
worker
.
id
}
/secrets/
{
secret
.
id
}
'
,
headers
=
{
"content-type"
:
"application/json"
},
headers
=
{
"content-type"
:
"application/json"
},
method
=
'delete'
)
method
=
'delete'
)
assert
response
.
status_code
==
204
assert
response
.
status_code
==
204
...
@@ -92,13 +92,13 @@ def test_delete_secret(client):
...
@@ -92,13 +92,13 @@ def test_delete_secret(client):
def
test_read_secret
(
client
):
def
test_read_secret
(
client
):
instance
=
Client
.
query
.
filter_by
(
codename
=
"executor"
).
first
()
instance
=
Client
.
query
.
filter_by
(
codename
=
"executor"
).
first
()
secret
=
Secret
.
query
.
filter_by
(
client
=
instance
).
first
()
secret
=
Secret
.
query
.
filter_by
(
client
=
instance
).
first
()
response
=
uti
ls
.
make_request
(
client
,
f
'/clients/
{
instance
.
id
}
/secrets/
{
secret
.
id
}
'
,
response
=
rest_too
ls
.
make_request
(
client
,
f
'/clients/
{
instance
.
id
}
/secrets/
{
secret
.
id
}
'
,
headers
=
{
"content-type"
:
"application/json"
},
headers
=
{
"content-type"
:
"application/json"
},
method
=
'get'
)
method
=
'get'
)
assert
response
.
status_code
==
200
assert
response
.
status_code
==
200
assert
response
.
mimetype
==
'application/json'
assert
response
.
mimetype
==
'application/json'
response_secret
=
uti
ls
.
extract_data
(
response
)
response_secret
=
rest_too
ls
.
extract_data
(
response
)
assert
response_secret
[
'id'
]
==
secret
.
id
assert
response_secret
[
'id'
]
==
secret
.
id
assert
response_secret
[
'name'
]
==
secret
.
name
assert
response_secret
[
'name'
]
==
secret
.
name
...
@@ -109,10 +109,10 @@ def test_update_secret(client):
...
@@ -109,10 +109,10 @@ def test_update_secret(client):
instance
=
Client
.
query
.
filter_by
(
codename
=
"executor"
).
first
()
instance
=
Client
.
query
.
filter_by
(
codename
=
"executor"
).
first
()
request_dict
=
dict
(
name
=
"new_name"
)
request_dict
=
dict
(
name
=
"new_name"
)
secret
=
Secret
.
query
.
filter_by
(
client
=
instance
).
first
()
secret
=
Secret
.
query
.
filter_by
(
client
=
instance
).
first
()
response
=
uti
ls
.
make_request
(
client
,
f
'/clients/
{
instance
.
id
}
/secrets/
{
secret
.
id
}
'
,
response
=
rest_too
ls
.
make_request
(
client
,
f
'/clients/
{
instance
.
id
}
/secrets/
{
secret
.
id
}
'
,
headers
=
{
"content-type"
:
"application/json"
},
headers
=
{
"content-type"
:
"application/json"
},
data
=
json
.
dumps
(
request_dict
),
data
=
json
.
dumps
(
request_dict
),
method
=
'put'
)
method
=
'put'
)
assert
response
.
status_code
==
204
assert
response
.
status_code
==
204
updated_secret
=
Secret
.
query
.
filter_by
(
client
=
instance
).
first
()
updated_secret
=
Secret
.
query
.
filter_by
(
client
=
instance
).
first
()
...
...
tests/rest/test_course.py
View file @
bf102b33
...
@@ -3,19 +3,19 @@ import json
...
@@ -3,19 +3,19 @@ import json
from
portal.database.models
import
Course
from
portal.database.models
import
Course
from
portal.service
import
courses
,
general
from
portal.service
import
courses
,
general
from
portal.service.courses
import
CourseService
from
portal.service.courses
import
CourseService
from
.
import
uti
ls
from
.
import
rest_too
ls
def
test_list
(
client
):
def
test_list
(
client
):
response
=
uti
ls
.
make_request
(
client
,
'/courses'
,
method
=
'get'
)
response
=
rest_too
ls
.
make_request
(
client
,
'/courses'
,
method
=
'get'
)
assert
response
.
status_code
==
200
assert
response
.
status_code
==
200
assert
response
.
mimetype
==
'application/json'
assert
response
.
mimetype
==
'application/json'
courses_response
=
uti
ls
.
extract_data
(
response
)
courses_response
=
rest_too
ls
.
extract_data
(
response
)
assert
len
(
courses_response
)
==
2
assert
len
(
courses_response
)
==
2
db_courses
=
Course
.
query
.
all
()
db_courses
=
Course
.
query
.
all
()
uti
ls
.
assert_course_in
(
db_courses
,
courses_response
[
0
])
rest_too
ls
.
assert_course_in
(
db_courses
,
courses_response
[
0
])
uti
ls
.
assert_course_in
(
db_courses
,
courses_response
[
1
])
rest_too
ls
.
assert_course_in
(
db_courses
,
courses_response
[
1
])
def
test_create
(
client
):
def
test_create
(
client
):
...
@@ -26,16 +26,16 @@ def test_create(client):
...
@@ -26,16 +26,16 @@ def test_create(client):
db_courses_number
=
len
(
Course
.
query
.
all
())
db_courses_number
=
len
(
Course
.
query
.
all
())
request_json
=
json
.
dumps
(
request_dict
)
request_json
=
json
.
dumps
(
request_dict
)
response
=
uti
ls
.
make_request
(
client
,
'/courses'
,
data
=
request_json
,