diff --git a/migrations/versions/3401e67c571b_.py b/migrations/versions/3401e67c571b_.py
deleted file mode 100644
index f4da2ef44199de432f5b960fb19ef535b5b67dd4..0000000000000000000000000000000000000000
--- a/migrations/versions/3401e67c571b_.py
+++ /dev/null
@@ -1,28 +0,0 @@
-"""empty message
-
-Revision ID: 3401e67c571b
-Revises: c21ce0e65d64
-Create Date: 2018-09-11 09:45:04.606844
-
-"""
-from alembic import op
-import sqlalchemy as sa
-
-
-# revision identifiers, used by Alembic.
-revision = '3401e67c571b'
-down_revision = 'c21ce0e65d64'
-branch_labels = None
-depends_on = None
-
-
-def upgrade():
-    # ### commands auto generated by Alembic - please adjust! ###
-    op.add_column('projectConfig', sa.Column('test_files_subdir', sa.String(length=50), nullable=True))
-    # ### end Alembic commands ###
-
-
-def downgrade():
-    # ### commands auto generated by Alembic - please adjust! ###
-    op.drop_column('projectConfig', 'test_files_subdir')
-    # ### end Alembic commands ###
diff --git a/migrations/versions/8c3c07862a02_.py b/migrations/versions/8c3c07862a02_.py
deleted file mode 100644
index 9a53c6cd9cd6f917e310c299abf727f7630ca20b..0000000000000000000000000000000000000000
--- a/migrations/versions/8c3c07862a02_.py
+++ /dev/null
@@ -1,32 +0,0 @@
-"""empty message
-
-Revision ID: 8c3c07862a02
-Revises: 0ad81fc4487e
-Create Date: 2018-09-04 14:24:06.598289
-
-"""
-from alembic import op
-import sqlalchemy as sa
-
-
-# revision identifiers, used by Alembic.
-revision = '8c3c07862a02'
-down_revision = '0ad81fc4487e'
-branch_labels = None
-depends_on = None
-
-
-def upgrade():
-    # ### commands auto generated by Alembic - please adjust! ###
-    op.add_column('submission', sa.Column('async_task_id', sa.String(length=36), nullable=True))
-    op.drop_column('submission', 'process_task_id')
-    op.drop_column('submission', 'storage_task_id')
-    # ### end Alembic commands ###
-
-
-def downgrade():
-    # ### commands auto generated by Alembic - please adjust! ###
-    op.add_column('submission', sa.Column('storage_task_id', sa.VARCHAR(length=36), autoincrement=False, nullable=True))
-    op.add_column('submission', sa.Column('process_task_id', sa.VARCHAR(length=36), autoincrement=False, nullable=True))
-    op.drop_column('submission', 'async_task_id')
-    # ### end Alembic commands ###
diff --git a/migrations/versions/0ad81fc4487e_.py b/migrations/versions/bd2121c14eaa_.py
similarity index 86%
rename from migrations/versions/0ad81fc4487e_.py
rename to migrations/versions/bd2121c14eaa_.py
index bec02e1491bfa498a03b424cd30b051533ddb2b3..34404f8a4cc0ba3b3d1f164e9174230b1bd749c8 100644
--- a/migrations/versions/0ad81fc4487e_.py
+++ b/migrations/versions/bd2121c14eaa_.py
@@ -1,16 +1,17 @@
 """empty message
 
-Revision ID: 0ad81fc4487e
+Revision ID: bd2121c14eaa
 Revises: 
-Create Date: 2018-09-02 17:09:55.862167
+Create Date: 2018-09-16 16:10:06.408159
 
 """
 from alembic import op
 import sqlalchemy as sa
+import portal.database.types
 
 
 # revision identifiers, used by Alembic.
-revision = '0ad81fc4487e'
+revision = 'bd2121c14eaa'
 down_revision = None
 branch_labels = None
 depends_on = None
@@ -21,7 +22,9 @@ def upgrade():
     op.create_table('client',
     sa.Column('id', sa.String(length=36), nullable=False),
     sa.Column('type', sa.Enum('USER', 'WORKER', name='ClientType'), nullable=False),
-    sa.PrimaryKeyConstraint('id')
+    sa.Column('codename', sa.String(length=30), nullable=False),
+    sa.PrimaryKeyConstraint('id'),
+    sa.UniqueConstraint('codename')
     )
     op.create_table('course',
     sa.Column('created_at', sa.TIMESTAMP(), nullable=True),
@@ -87,27 +90,23 @@ def upgrade():
     sa.Column('id', sa.String(length=36), nullable=False),
     sa.Column('uco', sa.Integer(), nullable=True),
     sa.Column('email', sa.String(length=50), nullable=False),
-    sa.Column('username', sa.String(length=30), nullable=False),
     sa.Column('name', sa.String(length=50), nullable=True),
     sa.Column('is_admin', sa.Boolean(), nullable=True),
     sa.Column('password_hash', sa.String(length=120), nullable=True),
     sa.ForeignKeyConstraint(['id'], ['client.id'], ),
     sa.PrimaryKeyConstraint('id'),
-    sa.UniqueConstraint('email'),
-    sa.UniqueConstraint('username')
+    sa.UniqueConstraint('email')
     )
     op.create_table('worker',
     sa.Column('created_at', sa.TIMESTAMP(), nullable=True),
     sa.Column('updated_at', sa.TIMESTAMP(), nullable=True),
     sa.Column('id', sa.String(length=36), nullable=False),
-    sa.Column('name', sa.String(length=30), nullable=False),
     sa.Column('url', sa.String(length=250), nullable=False),
     sa.Column('tags', sa.Text(), nullable=True),
     sa.Column('portal_secret', sa.String(length=64), nullable=True),
     sa.Column('state', sa.Enum('CREATED', 'READY', 'STOPPED', name='WorkerState'), nullable=False),
     sa.ForeignKeyConstraint(['id'], ['client.id'], ),
-    sa.PrimaryKeyConstraint('id'),
-    sa.UniqueConstraint('name')
+    sa.PrimaryKeyConstraint('id')
     )
     op.create_table('clients_roles',
     sa.Column('client_id', sa.String(length=36), nullable=True),
@@ -122,6 +121,7 @@ def upgrade():
     sa.Column('project_id', sa.String(length=36), nullable=False),
     sa.Column('submissions_cancellation_period', sa.Integer(), nullable=True),
     sa.Column('test_files_source', sa.String(length=600), nullable=True),
+    sa.Column('test_files_subdir', sa.String(length=50), nullable=True),
     sa.Column('test_files_commit_hash', sa.String(length=64), nullable=True),
     sa.Column('file_whitelist', sa.Text(), nullable=True),
     sa.Column('pre_submit_script', sa.Text(), nullable=True),
@@ -158,6 +158,7 @@ def upgrade():
     sa.Column('read_projects', sa.Boolean(), nullable=False),
     sa.Column('archive_projects', sa.Boolean(), nullable=False),
     sa.Column('create_submissions', sa.Boolean(), nullable=False),
+    sa.Column('create_submissions_other', sa.Boolean(), nullable=False),
     sa.Column('resubmit_submissions', sa.Boolean(), nullable=False),
     sa.Column('evaluate_submissions', sa.Boolean(), nullable=False),
     sa.Column('read_submissions_all', sa.Boolean(), nullable=False),
@@ -174,22 +175,21 @@ def upgrade():
     sa.PrimaryKeyConstraint('id')
     )
     op.create_table('submission',
-    sa.Column('created_at', sa.TIMESTAMP(), nullable=True),
-    sa.Column('updated_at', sa.TIMESTAMP(), nullable=True),
-    sa.Column('id', sa.String(length=36), nullable=False),
-    sa.Column('scheduled_for', sa.TIMESTAMP(timezone=True), nullable=True),
-    sa.Column('parameters', sa.Text(), nullable=False),
-    sa.Column('state', sa.Enum('CREATED', 'READY', 'QUEUED', 'IN_PROGRESS', 'FINISHED', 'CANCELLED', 'ABORTED', 'ARCHIVED', name='SubmissionState'), nullable=False),
-    sa.Column('note', sa.Text(), nullable=True),
-    sa.Column('source_hash', sa.String(length=64), nullable=True),
-    sa.Column('user_id', sa.String(length=36), nullable=False),
-    sa.Column('project_id', sa.String(length=36), nullable=False),
-    sa.Column('storage_task_id', sa.String(length=36), nullable=True),
-    sa.Column('process_task_id', sa.String(length=36), nullable=True),
-    sa.ForeignKeyConstraint(['project_id'], ['project.id'], ondelete='cascade'),
-    sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='cascade'),
-    sa.PrimaryKeyConstraint('id')
-    )
+                    sa.Column('created_at', sa.TIMESTAMP(), nullable=True),
+                    sa.Column('updated_at', sa.TIMESTAMP(), nullable=True),
+                    sa.Column('id', sa.String(length=36), nullable=False),
+                    sa.Column('scheduled_for', sa.TIMESTAMP(timezone=True), nullable=True),
+                    sa.Column('parameters', portal.database.types.JSONEncodedDict(), nullable=True),
+                    sa.Column('state', sa.Enum('CREATED', 'READY', 'QUEUED', 'IN_PROGRESS', 'FINISHED', 'CANCELLED', 'ABORTED', 'ARCHIVED', name='SubmissionState'), nullable=False),
+                    sa.Column('note', portal.database.types.JSONEncodedDict(), nullable=True),
+                    sa.Column('source_hash', sa.String(length=64), nullable=True),
+                    sa.Column('user_id', sa.String(length=36), nullable=False),
+                    sa.Column('project_id', sa.String(length=36), nullable=False),
+                    sa.Column('async_task_id', sa.String(length=36), nullable=True),
+                    sa.ForeignKeyConstraint(['project_id'], ['project.id'], ondelete='cascade'),
+                    sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='cascade'),
+                    sa.PrimaryKeyConstraint('id')
+                    )
     op.create_table('users_groups',
     sa.Column('user_id', sa.String(length=36), nullable=True),
     sa.Column('group_id', sa.String(length=36), nullable=True),
diff --git a/migrations/versions/c21ce0e65d64_.py b/migrations/versions/c21ce0e65d64_.py
deleted file mode 100644
index 14c3ccc2987d1f733d271589bdb1decf5a68a5f0..0000000000000000000000000000000000000000
--- a/migrations/versions/c21ce0e65d64_.py
+++ /dev/null
@@ -1,32 +0,0 @@
-"""empty message
-
-Revision ID: c21ce0e65d64
-Revises: 8c3c07862a02
-Create Date: 2018-09-10 20:45:32.588254
-
-"""
-from alembic import op
-import sqlalchemy as sa
-
-
-# revision identifiers, used by Alembic.
-revision = 'c21ce0e65d64'
-down_revision = '8c3c07862a02'
-branch_labels = None
-depends_on = None
-
-
-def upgrade():
-    # ### commands auto generated by Alembic - please adjust! ###
-    op.alter_column('submission', 'parameters',
-               existing_type=sa.TEXT(),
-               nullable=True)
-    # ### end Alembic commands ###
-
-
-def downgrade():
-    # ### commands auto generated by Alembic - please adjust! ###
-    op.alter_column('submission', 'parameters',
-               existing_type=sa.TEXT(),
-               nullable=False)
-    # ### end Alembic commands ###
diff --git a/portal/database/models.py b/portal/database/models.py
index 6d5e1e5436601947a5ec4d2d05cd20553d66e876..988dbcf44809a1451ad69f15d7075747edba10f7 100644
--- a/portal/database/models.py
+++ b/portal/database/models.py
@@ -3,42 +3,25 @@ Models module where all of the models are specified
 """
 
 import enum
-import json
 import logging
 import uuid
 from typing import List
 
-import sqlalchemy
 from flask_sqlalchemy import BaseQuery
-from sqlalchemy import TypeDecorator, event
+from sqlalchemy import event
 from sqlalchemy.ext.hybrid import hybrid_property
 from werkzeug.security import check_password_hash, generate_password_hash
 
 from portal import db
 from portal.database.exceptions import PortalDbError
 from portal.database.mixins import EntityBase, NamedMixin
+from portal.database.types import JSONEncodedDict
 from portal.tools import time
 from portal.tools.time import normalize_time
 
 log = logging.getLogger(__name__)
 
 
-class JSONEncodedDict(TypeDecorator):
-    "Represents an immutable structure as a json-encoded string."
-
-    impl = sqlalchemy.Text
-
-    def process_bind_param(self, value, dialect):
-        if value is not None:
-            value = json.dumps(value)
-        return value
-
-    def process_result_value(self, value, dialect):
-        if value is not None:
-            value = json.loads(value)
-        return value
-
-
 def _repr(instance) -> str:
     """Repr helper function
     Args:
diff --git a/portal/database/types.py b/portal/database/types.py
new file mode 100644
index 0000000000000000000000000000000000000000..f7e532bea644f82f90b68b32233e7e1211546552
--- /dev/null
+++ b/portal/database/types.py
@@ -0,0 +1,20 @@
+import json
+
+import sqlalchemy
+from sqlalchemy import TypeDecorator
+
+
+class JSONEncodedDict(TypeDecorator):
+    "Represents an immutable structure as a json-encoded string."
+
+    impl = sqlalchemy.Text
+
+    def process_bind_param(self, value, dialect):
+        if value is not None:
+            value = json.dumps(value)
+        return value
+
+    def process_result_value(self, value, dialect):
+        if value is not None:
+            value = json.loads(value)
+        return value
\ No newline at end of file
diff --git a/portal/rest/schemas.py b/portal/rest/schemas.py
index c8935a22386a1e8f958202aa01e8f1216c16afc2..227320a9fcfe9f6774a9ab7d465cc38113ed9598 100644
--- a/portal/rest/schemas.py
+++ b/portal/rest/schemas.py
@@ -302,7 +302,7 @@ class SecretSchema(BaseSchema, Schema):
     """
     name = fields.Str()
     expires_at = fields.LocalDateTime(dump_only=True)
-    client = NESTED('permissions')
+    client = NESTED('client')
 
 
 class CourseImportConfigSchema(Schema):
@@ -346,15 +346,6 @@ class ProjectImportSchema(Schema):
     source_project = fields.Str()
 
 
-class NotificationSendToSchema(Schema):
-    """Notification Send To Schema
-    """
-    role = fields.Str()
-    users = fields.List(fields.Str())
-    group = fields.Str()
-    course = fields.Str()
-
-
 class SubmissionResultTemplateSchema(Schema):
     """Submission Result Template Schema
     """
diff --git a/portal/service/auth.py b/portal/service/auth.py
index 194b18ef75a0d4348ffe59d55f15a22c55f0e591..6884ac91557a37477a88ca27953bfb124b7c1613 100644
--- a/portal/service/auth.py
+++ b/portal/service/auth.py
@@ -68,7 +68,7 @@ def login_secret(identifier: str, secret: str) -> Client:
 
 
 def validate_gitlab_token(token: str, username: str, throws: bool = True):
-    """Validates gitlab access token using the gitlab permissions
+    """Validates gitlab access token using the gitlab client
     Args:
         token(str): Gitlab access token
         username(str): Username
diff --git a/portal/service/errors.py b/portal/service/errors.py
index 55ee1d1afef8514d0619b058531c6741bee73118..f531d0cdc0a3d3e9724550eb22b480eaf41f1291 100644
--- a/portal/service/errors.py
+++ b/portal/service/errors.py
@@ -68,7 +68,7 @@ class DataMissingError(PortalAPIError):
             resource(str): Name of the resource
         """
         message = dict(action=action, resource=resource,
-                       message='Data is missing!')
+                       message='Data is missing')
         super(DataMissingError, self).__init__(code=400, message=message)
 
 
@@ -96,9 +96,7 @@ class ResourceNotFoundError(PortalAPIError):
 
 class UnauthorizedError(PortalAPIError):
     def __init__(self, note=None):
-        message = dict(
-            message=f"You are not authorized.",
-        )
+        message = dict(message=f"You are not authorized.",)
         if note:
             message['note'] = note
 
@@ -108,7 +106,7 @@ class UnauthorizedError(PortalAPIError):
 class ForbiddenError(PortalAPIError):
     # could use a resource identification (like 404)
     def __init__(self, client=None, note=None):
-        user_message = f"Forbidden for {client.type}: {client.id} ({client.codename})!" if client else \
+        user_message = f"Forbidden for {client.type}: {client.id} ({client.codename})" if client else \
             'Forbidden action.'
         message = dict(uid=client.id, message=user_message)
         if note:
diff --git a/portal/service/groups.py b/portal/service/groups.py
index fef9811bb90082647121107f3c4d43d04864eba2..cd572ab0224c369efbe34b3c8f98e5b4a4aafd57 100644
--- a/portal/service/groups.py
+++ b/portal/service/groups.py
@@ -182,7 +182,6 @@ class GroupService:
         """List all groups
         Args:
             course(Course): Course instance
-            permissions: Client instance
 
         Returns(list): List of all groups
 
diff --git a/portal/service/permissions.py b/portal/service/permissions.py
index e1274b8589539a1e89d735b4bfcc6524053f5626..d7c7c44057a15ec153abc9f7ea06d091eefd60c7 100644
--- a/portal/service/permissions.py
+++ b/portal/service/permissions.py
@@ -189,14 +189,14 @@ class PermissionsService:
         return self._course
 
     def get_effective_permissions(self, course_id: str = None) -> dict:
-        """Gets effective permissions for a permissions in course.
-        If no course is specified, returns the permissions's
+        """Gets effective permissions for a course in course.
+        If no course is specified, returns the client's
         effective permissions in all courses he is a part of.
 
         Args:
             course_id(str): Course ID
 
-        Returns(dict): Effective permissions for the permissions. Keys are course IDs, values
+        Returns(dict): Effective permissions for the course. Keys are course IDs, values
         dictionaries of permissions with their values.
         """
         course = general.find_course(course_id, throws=False)
@@ -204,7 +204,7 @@ class PermissionsService:
         return self.build_effective_permissions(*courses)
 
     def build_effective_permissions(self, *courses) -> dict:
-        """Builds effective permissions in a list of courses for the permissions
+        """Builds effective permissions in a list of courses for the client
 
         Args:
             *courses: List of courses
@@ -217,7 +217,7 @@ class PermissionsService:
         return result
 
     def effective_permissions_for_course(self, course: Course = None) -> dict:
-        """Extracts effective permissions for a permissions in one course
+        """Extracts effective permissions for a client in one course
 
         Returns(dict): Effective permissions dictionary
         """
diff --git a/portal/service/projects.py b/portal/service/projects.py
index 3ed8acf37c74e0bc024404dbce9ef607825489f3..a90d036a5ed9423b52c6fbb4af32d57b6c4de1a7 100644
--- a/portal/service/projects.py
+++ b/portal/service/projects.py
@@ -145,10 +145,7 @@ class ProjectService:
         """List of all projects
         Args:
             course(Course): Course instance
-            permissions: Client instance
-
         Returns(list): list of projects
-
         """
         perm_service = permissions.PermissionsService(course=course)
         if perm_service.check.permissions(['view_course_full']):
diff --git a/portal/service/roles.py b/portal/service/roles.py
index 0c114588e44e963e49127809de4bbdfddd1a18d9..af41a6439b33e966de050091a75a32ec57c5bc3c 100644
--- a/portal/service/roles.py
+++ b/portal/service/roles.py
@@ -101,14 +101,14 @@ class RoleService:
         """Finds all clients based on their ids
 
         Args:
-            ids(List[str]): List of permissions ids
+            ids(List[str]): List of clients ids
 
         Returns(List[Client]): List of clients
         """
         return [find_client(i) for i in ids]
 
     def update_clients_membership(self, data: dict) -> Role:
-        """Updates permissions membership in the role
+        """Updates client membership in the role
         Args:
             data(dict): Data provided to update role membership
 
@@ -155,7 +155,6 @@ class RoleService:
     def remove_client(self, client: Client) -> Role:
         """Removes single client from the role
         Args:
-            role(Role): Role instance
             client(Client): Client instance
         Returns(Role): Updated role
         """
@@ -175,8 +174,6 @@ class RoleService:
         """List of all roles
         Args:
             course(Course): Course instance
-            permissions(Client): Client instance
-
         Returns(list): List of roles
 
         """
diff --git a/portal/service/users.py b/portal/service/users.py
index c463374575e64016f062fb7eadbe2657a7e91432..e135a20f6530c06f4354702ed5c14febc96f4b8b 100644
--- a/portal/service/users.py
+++ b/portal/service/users.py
@@ -110,7 +110,7 @@ class UserService:
         return self.user
 
     def update_password(self, data: dict):
-        log.info(f"[UPDATE] User password: {self.user.id} by {self.permissions.id}")
+        log.info(f"[UPDATE] User password: {self.user.id} by {self.client.id}")
         self.__require_param(data, 'new_password')
         if self.client == self.user and not self.user.is_admin:
             self.__check_old_password(data)
@@ -172,7 +172,6 @@ class UserService:
         """Find all groups for the user, optionally filtered by course.
 
         Args:
-            user(User): User instance
             course_id(str): Course id (optional)
 
         Returns(List[Group]): List of all groups
@@ -185,7 +184,6 @@ class UserService:
         """Get all roles for the user, optionally filtered by course
 
         Args:
-            user(User): User instance
             course_id(str): Course id (optional)
 
         Returns(List[Role]):
@@ -198,9 +196,6 @@ class UserService:
     def find_reviews(self) -> List[Review]:
         """Gets reviews the user has contributed to.
 
-        Args:
-            user(User): User instance
-
         Returns(List[Review]):
         """
         reviews = []
@@ -214,7 +209,6 @@ class UserService:
         """Get all submissions of a user, optionally filtered by course and project.
 
         Args:
-            user(User):
             course_id(str): Course id (optional)
             project_ids(List[str]): List of project ids (optional)
 
diff --git a/portal/tools/gitlab_client.py b/portal/tools/gitlab_client.py
index f6e67de7a1dc5d7eb8b9f3450f88777b9c8351d2..8ef0588de469a387a806dd92132fa767f2d3ff89 100644
--- a/portal/tools/gitlab_client.py
+++ b/portal/tools/gitlab_client.py
@@ -1,5 +1,5 @@
 """
-Gitlab permissions module
+Gitlab client module
 """
 
 import gitlab
@@ -7,7 +7,7 @@ from flask import Flask
 
 
 class GitlabFactory(object):
-    """Gitlab permissions wrapper for flask
+    """Gitlab client wrapper for flask
     DOC: http://python-gitlab.readthedocs.io/en/stable/api-usage.html
     """
 
@@ -19,19 +19,19 @@ class GitlabFactory(object):
         self.app: Flask = app
 
     def init_app(self, app: Flask):
-        """Initializes the permissions with a flask application
+        """Initializes the client with a flask application
         Args:
             app(Flask): Flask application
         """
         self.app = app
 
     def instance(self, *args, **kwargs) -> gitlab.Gitlab:
-        """Creates instance of the Gitlab permissions
+        """Creates instance of the Gitlab client
         Args:
             *args:
             **kwargs:
 
-        Returns(gitlab.Gitlab): Gitlab permissions instance
+        Returns(gitlab.Gitlab): Gitlab client instance
         """
         gitlab_url = self.app.config.get('GITLAB_URL')
         return gitlab.Gitlab(gitlab_url, *args, **kwargs)
diff --git a/tests/database/test_db.py b/tests/database/test_db.py
index a482c17275b75f2b3145ed5f65a06da1047d3ab3..fe05df38db9c99db01d3beb628d7af56d7f674b1 100644
--- a/tests/database/test_db.py
+++ b/tests/database/test_db.py
@@ -228,7 +228,7 @@ def test_submission_create_valid(session):
     user = User(uco=123, email='foo', username='xfoo')
     course = Course(name="C++", codename="testcourse1")
     project = Project(course=course, name="p1")
-    submission = Submission(user=user, project=project, parameters="")
+    submission = Submission(user=user, project=project, parameters={})
     session.add(submission)
     session.flush()
 
@@ -243,7 +243,7 @@ def test_submission_update_user(session):
     user2 = User(uco=456, email='bar', username='xbar')
     course = Course(name="C++", codename="testcourse1")
     project = Project(course=course, codename="p1")
-    submission = Submission(user=user1, project=project, parameters="")
+    submission = Submission(user=user1, project=project, parameters={})
 
     session.add_all([submission, user2])
     session.flush()
@@ -581,7 +581,7 @@ def test_relation_course_project_delete_project_entity(session):
     assert len(Project.query.all()) == 2
 
 
-# permissions-role-course
+# client-role-course
 def test_relation_client_role(session):
     user1 = User(uco=123, email="foo", username="xfoo")
     user2 = User(uco=456, email="bar", username="xbar")
@@ -833,7 +833,7 @@ def test_user_submission_review(session):
     course = Course(name="C++", codename="PB161")
     project = Project(course=course, name="p1")
 
-    submission = Submission(user=user, project=project, parameters="")
+    submission = Submission(user=user, project=project, parameters={})
     session.add(submission)
     session.flush()
     assert submission in user.submissions
diff --git a/tests/rest/test_project.py b/tests/rest/test_project.py
index 4b9e27b36952128b8d78dc470dc6850a2d4aa859..5ccf8bb2cdaf1187f1e0adb1c3eff3bcb4d48a56 100644
--- a/tests/rest/test_project.py
+++ b/tests/rest/test_project.py
@@ -177,7 +177,7 @@ def test_create_submission(client):
     p_submissions = len(p.submissions)
 
     request_dict = {
-        "project_params": "data for Kontr",
+        "project_params": {},
         "file_params": {
             "source": {
                 "type": "git",
@@ -187,7 +187,7 @@ def test_create_submission(client):
             }
         }
     }
-    request_json = json.dumps(request_dict, cls=utils.DateTimeEncoder)
+    request_json = json.dumps(request_dict)
 
     path = f"/courses/{cpp.codename}/projects/{p.name}/submissions"
     response = utils.make_request(
@@ -212,7 +212,7 @@ def test_create_submission_as_different_user(client):
     p_submissions = len(p.submissions)
 
     request_dict = {
-        "project_params": "data for Kontr",
+        "project_params": {},
         "file_params": {
             "source": {
                 "type": "git",
@@ -222,7 +222,7 @@ def test_create_submission_as_different_user(client):
             }
         }
     }
-    request_json = json.dumps(request_dict, cls=utils.DateTimeEncoder)
+    request_json = json.dumps(request_dict)
 
     path = f"/courses/{cpp.codename}/projects/{p.name}/submissions?user=student1"
     response = utils.make_request(client, path, data=request_json, method='post')
diff --git a/tests/rest/utils.py b/tests/rest/utils.py
index deb5e9e20e14490c4469e81fa509a46cf6e5c104..215004933cd8f492fbac9887e4223cb228289df5 100644
--- a/tests/rest/utils.py
+++ b/tests/rest/utils.py
@@ -31,7 +31,7 @@ def make_request(client: FlaskClient, url: str, method: str,
     """ Creates an authenticated request to an endpoint.
 
     Args:
-        client: Flask's test permissions
+        client: Flask's test client
         url: request url
         method: get, post, put
         credentials: json data for login