Verified Commit 6b8f2b86 authored by Peter Stanko's avatar Peter Stanko
Browse files

List of clients in the course

parent 6f057659
......@@ -94,6 +94,7 @@ class TestConfig(Config):
BROKER_URL = 'redis://'
CELERY_RESULT_BACKEND = BROKER_URL
PORTAL_LOG_CONFIG = False
GIT_REPO_BASE = os.getenv('GIT_REPO_BASE', f"git@gitlab.local")
# pylint: enable=too-few-public-methods
......
......@@ -392,7 +392,7 @@ class Course(db.Model, EntityBase, NamedMixin):
.join(User.roles).filter((Role.id == role.id) & (Role.course == self)) \
.all()
def get_users_filtered(self, groups: List['Group'], roles: List['Role']):
def get_clients_filtered(self, groups: List['Group'], roles: List['Role']):
"""Gets all users in the course who are members of at least one of
the provided groups and have at least one of the specified roles.
......@@ -406,13 +406,13 @@ class Course(db.Model, EntityBase, NamedMixin):
(are in at least one group AND have at least one role).
"""
query = User.query.join(User.roles).filter(Role.course_id == self.id)
query = Client.query.join(Client.roles).filter(Role.course_id == self.id)
if roles:
role_ids = [role.id for role in roles]
query = query.filter(Role.id.in_(role_ids))
if groups:
group_ids = [group.id for group in groups]
query = query.join(User.groups).filter(Group.id.in_(group_ids)).filter(
query = query.join(Client.groups).filter(Group.id.in_(group_ids)).filter(
Group.course_id == self.id)
return query.all()
......
......@@ -138,10 +138,10 @@ class CourseImport(CustomResource):
return SCHEMAS.dump('course', copied_course)
@courses_namespace.route('/<string:cid>/users')
@courses_namespace.route('/<string:cid>/clients')
@courses_namespace.param('cid', 'Course id')
@courses_namespace.response(404, 'Course not found')
class CourseUsers(CustomResource):
class CourseClients(CustomResource):
@jwt_required
# @courses_namespace.response(200, 'Users in the course', model=users_schema)
@courses_namespace.response(403, 'Not allowed to see users in the course')
......@@ -150,5 +150,5 @@ class CourseUsers(CustomResource):
self.permissions(course=course).require.permissions(['view_course_full'])
group_ids = request.args.getlist('group')
role_ids = request.args.getlist('role')
users = self.rest.courses(course).get_users_filtered(group_ids, role_ids)
users = self.rest.courses(course).get_clients_filtered(group_ids, role_ids)
return SCHEMAS.dump('users', users)
......@@ -383,7 +383,7 @@ class Schemas:
'user_reduced': (*ALWAYS_ALLOWED, 'username', 'uco', 'email', 'name'),
'users': (*ALWAYS_ALLOWED, 'username', 'uco', 'email'),
'submissions': (*ALWAYS_ALLOWED, 'course', 'state', 'project', 'scheduled_for', 'user'),
'submission_state': (*ALWAYS_ALLOWED, 'state'),
'submission_state': (*ALWAYS_ALLOWED, 'state', 'parameters', 'scheduled_for'),
'roles': ENT_W_COURSE,
'groups': ENT_W_COURSE,
'projects': ENT_W_COURSE,
......
......@@ -76,14 +76,13 @@ class CourseService(GeneralService):
log.info(f"[UPDATE] Notes access token {self.course.log_name}: {token}")
return self.course
def get_users_filtered(self, groups: List[str], roles: List[str]) -> List[User]:
def get_clients_filtered(self, groups: List[str], roles: List[str]) -> List[User]:
"""Get all users for course filtered
Args:
groups(list): Group names list
roles(list): Role names list
Returns(List[User]):
"""
groups_entities = Group.query.filter(Group.id.in_(groups)).all()
roles_entities = Role.query.filter(Role.id.in_(roles)).all()
return self.course.get_users_filtered(groups_entities, roles_entities)
groups_entities = Group.query.filter(Group.id.in_(groups)).all() if groups else None
roles_entities = Role.query.filter(Role.id.in_(roles)).all() if roles else None
return self.course.get_clients_filtered(groups_entities, roles_entities)
......@@ -24,6 +24,10 @@ class GeneralService:
self._rest_service: RestService = rest_service
self._entity = None
@property
def flask_app(self) -> flask.Flask:
return flask.current_app
@property
def find(self):
return self._rest_service.find
......
......@@ -202,10 +202,12 @@ class SubmissionsService(GeneralService):
def process_submission_params(self, params: dict, project: Project, user: User):
file_params = params.get('file_params')
file_params['from_dir'] = params.get('from_dir') or project.codename
source = file_params.get('source')
if source and source['type'] == 'git':
source['url'] = source.get('url') or self.__get_default_git_url(project, user)
url = source.get('url')
if not url:
source['url'] = self.__get_default_git_url(project, user)
file_params['from_dir'] = params.get('from_dir') or project.codename
return params
def __get_default_git_url(self, project: Project, user: User):
......
......@@ -79,6 +79,19 @@ def test_read(client):
rest_tools.assert_course(c, course)
def test_read_course_users(client):
course = Course.query.filter_by(codename="testcourse2").first()
response = rest_tools.make_request(client, f"/courses/{course.id}/clients")
assert_response(response, 200)
users = rest_tools.extract_data(response)
course_users = set()
for role in course.roles:
course_users.update(role.clients)
assert users
assert len(users) == 4
assert len(course_users) == len(users)
def test_update(client):
c = Course.query.filter_by(codename="testcourse1").first()
request_dict = dict(
......
......@@ -3,6 +3,7 @@ from datetime import timedelta
import pytest
from flask_jwt_extended import create_access_token
from mock import patch
from portal.database.models import Course, Project, User
from portal.tools.time import current_time, strip_seconds
......@@ -177,6 +178,7 @@ def request_dict() -> dict:
}
@pytest.mark.celery(result_backend='redis://')
def test_create_submission(client, request_dict):
cpp = Course.query.filter_by(codename="testcourse1").first()
p = cpp.projects[0]
......@@ -198,6 +200,7 @@ def test_create_submission(client, request_dict):
rest_tools.assert_submission_in(user_updated.submissions, new_submission)
@pytest.mark.celery(result_backend='redis://')
def test_create_submission_as_different_user(client, rest_service, request_dict):
cpp = rest_service.find.course("testcourse1")
proj = cpp.projects[0]
......@@ -217,6 +220,7 @@ def test_create_submission_as_different_user(client, rest_service, request_dict)
rest_tools.assert_submission_in(user_updated.submissions, new_submission)
@pytest.mark.celery(result_backend='redis://')
def test_create_submission_as_student(client, ent_mocker, rest_service, request_dict):
user, course, project = ent_mocker.create_user_in_course('testuser', role_type='student')
path = f"/courses/{course.codename}/projects/{project.name}/submissions"
......@@ -229,6 +233,7 @@ def test_create_submission_as_student(client, ent_mocker, rest_service, request_
assert new_submission['id']
@pytest.mark.celery(result_backend='redis://')
def test_create_submission_second_should_fail(client, ent_mocker, rest_service, request_dict):
user, course, project = ent_mocker.create_user_in_course('testuser', role_type='student')
path = f"/courses/{course.codename}/projects/{project.name}/submissions"
......@@ -244,3 +249,36 @@ def test_create_submission_second_should_fail(client, ent_mocker, rest_service,
credentials=user_credentials)
assert_response(response, code=429)
@pytest.fixture()
def defaults_dict():
return {
"project_params": {},
"file_params": {
"source": {
"type": "git",
"branch": "master",
"checkout": "master"
}
}
}
@pytest.mark.celery(result_backend='redis://')
def test_create_submission_as_with_default_params(client, ent_mocker, rest_service, defaults_dict):
user, course, project = ent_mocker.create_user_in_course('testuser', role_type='student')
path = f"/courses/{course.codename}/projects/{project.name}/submissions"
user_credentials = get_user_credentials(user.username)
response = rest_tools.make_request(client, path, json=defaults_dict, method='post',
credentials=user_credentials)
assert_response(response, code=201)
new_submission = rest_tools.extract_data(response)
assert new_submission['id']
submission = rest_service.find.submission(new_submission['id'])
assert submission.project == project
assert submission.course == course
assert submission.user == user
assert submission.parameters['file_params']['from_dir'] == project.codename
gitlab_url = f'git@gitlab.local/{user.username}/{course.codename}'
assert submission.parameters['file_params']['source']['url'] == gitlab_url
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment