diff --git a/README.md b/README.md index 77b040e..270d20f 100644 --- a/README.md +++ b/README.md @@ -111,8 +111,11 @@ run wsgidav server: tracimcli webdav start + ## Run Tests and others checks ## +### Run Tests ### + Before running some functional test related to email, you need a local working *MailHog* see here : https://github.com/mailhog/MailHog diff --git a/tests_configs.ini b/tests_configs.ini index 4c2b2ce..1367264 100644 --- a/tests_configs.ini +++ b/tests_configs.ini @@ -5,6 +5,14 @@ depot_storage_dir = /tmp/test/depot user.auth_token.validity = 604800 preview_cache_dir = /tmp/test/preview_cache +[app:command_test] +use = egg:tracim_backend +sqlalchemy.url = sqlite:///tracim_test.sqlite +depot_storage_name = test +depot_storage_dir = /tmp/test/depot +user.auth_token.validity = 604800 +preview_cache_dir = /tmp/test/preview_cache + [mail_test] sqlalchemy.url = sqlite:///:memory: depot_storage_name = test @@ -54,4 +62,4 @@ email.processing_mode = async email.notification.smtp.server = 127.0.0.1 email.notification.smtp.port = 1025 email.notification.smtp.user = test_user -email.notification.smtp.password = just_a_password \ No newline at end of file +email.notification.smtp.password = just_a_password diff --git a/tracim/command/__init__.py b/tracim/command/__init__.py index 5ca17fc..8b850d2 100644 --- a/tracim/command/__init__.py +++ b/tracim/command/__init__.py @@ -9,7 +9,7 @@ from pyramid.paster import bootstrap from pyramid.scripting import AppEnvironment -from tracim.exceptions import CommandAbortedError +from tracim.exceptions import BadCommandError from tracim.lib.utils.utils import DEFAULT_TRACIM_CONFIG_FILE @@ -56,6 +56,7 @@ def take_action(self, parsed_args: argparse.Namespace) -> None: with app_context['request'].tm: self.take_app_action(parsed_args, app_context) + def get_parser(self, prog_name: str) -> argparse.ArgumentParser: parser = super(AppContextCommand, self).get_parser(prog_name) diff --git a/tracim/command/user.py b/tracim/command/user.py index c09de3f..902cfdc 100644 --- a/tracim/command/user.py +++ b/tracim/command/user.py @@ -3,17 +3,15 @@ from pyramid.scripting import AppEnvironment import transaction from sqlalchemy.exc import IntegrityError +from sqlalchemy.orm.exc import NoResultFound from tracim import CFG from tracim.command import AppContextCommand from tracim.command import Extender -#from tracim.lib.auth.ldap import LDAPAuth -#from tracim.lib.daemons import DaemonsManager -#from tracim.lib.daemons import RadicaleDaemon -#from tracim.lib.email import get_email_manager -from tracim.exceptions import AlreadyExistError +from tracim.exceptions import UserAlreadyExistError +from tracim.exceptions import GroupDoesNotExist from tracim.exceptions import NotificationNotSend -from tracim.exceptions import CommandAbortedError +from tracim.exceptions import BadCommandError from tracim.lib.core.group import GroupApi from tracim.lib.core.user import UserApi from tracim.models import User @@ -85,6 +83,14 @@ def _user_exist(self, login: str) -> User: return self._user_api.user_with_email_exists(login) def _get_group(self, name: str) -> Group: + groups_availables = [group.group_name + for group in self._group_api.get_all()] + if name not in groups_availables: + msg = "Group '{}' does not exist, choose a group name in : ".format(name) # nopep8 + for group in groups_availables: + msg+= "'{}',".format(group) + self._session.rollback() + raise GroupDoesNotExist(msg) return self._group_api.get_one_with_name(name) def _add_user_to_named_group( @@ -92,6 +98,7 @@ def _add_user_to_named_group( user: str, group_name: str ) -> None: + group = self._get_group(group_name) if user not in group.users: group.users.append(user) @@ -116,7 +123,7 @@ def _create_user( ) -> User: if not password: if self._password_required(): - raise CommandAbortedError( + raise BadCommandError( "You must provide -p/--password parameter" ) password = '' @@ -135,7 +142,7 @@ def _create_user( self._user_api.execute_created_user_actions(user) except IntegrityError: self._session.rollback() - raise AlreadyExistError() + raise UserAlreadyExistError() except NotificationNotSend as exception: self._session.rollback() raise exception @@ -182,10 +189,10 @@ def _proceed_user(self, parsed_args: argparse.Namespace) -> User: password=parsed_args.password, do_notify=parsed_args.send_email, ) - except AlreadyExistError: - raise CommandAbortedError("Error: User already exist (use `user update` command instead)") + except UserAlreadyExistError: + raise UserAlreadyExistError("Error: User already exist (use `user update` command instead)") except NotificationNotSend: - raise CommandAbortedError("Error: Cannot send email notification, user not created.") + raise NotificationNotSend("Error: Cannot send email notification, user not created.") # TODO - G.M - 04-04-2018 - [Email] Check this code # if parsed_args.send_email: # email_manager = get_email_manager() @@ -243,5 +250,5 @@ class UpdateUserCommand(UserCommand): action = UserCommand.ACTION_UPDATE -class LDAPUserUnknown(CommandAbortedError): +class LDAPUserUnknown(BadCommandError): pass diff --git a/tracim/exceptions.py b/tracim/exceptions.py index 4c3aabd..e80a26e 100644 --- a/tracim/exceptions.py +++ b/tracim/exceptions.py @@ -25,15 +25,11 @@ class ConfigurationError(TracimError): pass -class AlreadyExistError(TracimError): +class UserAlreadyExistError(TracimError): pass -class CommandError(TracimError): - pass - - -class CommandAbortedError(CommandError): +class BadCommandError(TracimError): pass @@ -93,13 +89,17 @@ class WrongUserPassword(TracimException): pass -class UserDoesNotExist(TracimException): +class NotificationNotSend(TracimException): pass -class UserNotFoundInTracimRequest(TracimException): +class GroupDoesNotExist(TracimError): pass -class NotificationNotSend(TracimException): +class UserDoesNotExist(TracimException): pass + + +class UserNotFoundInTracimRequest(TracimException): + pass \ No newline at end of file diff --git a/tracim/lib/core/group.py b/tracim/lib/core/group.py index 69927d1..c6afce3 100644 --- a/tracim/lib/core/group.py +++ b/tracim/lib/core/group.py @@ -1,8 +1,12 @@ # -*- coding: utf-8 -*- import typing +from sqlalchemy.orm.exc import NoResultFound + +from tracim.exceptions import GroupDoesNotExist from tracim import CFG + __author__ = 'damien' from tracim.models.auth import Group, User @@ -26,7 +30,18 @@ def _base_query(self) -> Query: return self._session.query(Group) def get_one(self, group_id) -> Group: - return self._base_query().filter(Group.group_id == group_id).one() + try: + group = self._base_query().filter(Group.group_id == group_id).one() + return group + except NoResultFound: + raise GroupDoesNotExist() def get_one_with_name(self, group_name) -> Group: - return self._base_query().filter(Group.group_name == group_name).one() + try: + group = self._base_query().filter(Group.group_name == group_name).one() + return group + except NoResultFound: + raise GroupDoesNotExist() + + def get_all(self): + return self._base_query().order_by(Group.group_id).all() diff --git a/tracim/tests/__init__.py b/tracim/tests/__init__.py index dc2cc04..c397487 100644 --- a/tracim/tests/__init__.py +++ b/tracim/tests/__init__.py @@ -35,8 +35,9 @@ class FunctionalTest(unittest.TestCase): sqlalchemy_url = 'sqlite:///tracim_test.sqlite' def setUp(self): + logger._logger.setLevel('WARNING') DepotManager._clear() - settings = { + self.settings = { 'sqlalchemy.url': self.sqlalchemy_url, 'user.auth_token.validity': '604800', 'depot_storage_dir': '/tmp/test/depot', @@ -45,19 +46,24 @@ def setUp(self): } hapic.reset_context() - app = web({}, **settings) - self.init_database(settings) + self.engine = get_engine(self.settings) + DeclarativeBase.metadata.create_all(self.engine) + self.session_factory = get_session_factory(self.engine) + self.app_config = CFG(self.settings) + self.app_config.configure_filedepot() + self.init_database(self.settings) + DepotManager._clear() + self.run_app() + + def run_app(self): + app = web({}, **self.settings) self.testapp = TestApp(app) def init_database(self, settings): - self.engine = get_engine(settings) - DeclarativeBase.metadata.create_all(self.engine) - session_factory = get_session_factory(self.engine) - app_config = CFG(settings) with transaction.manager: - dbsession = get_tm_session(session_factory, transaction.manager) + dbsession = get_tm_session(self.session_factory, transaction.manager) try: - fixtures_loader = FixturesLoader(dbsession, app_config) + fixtures_loader = FixturesLoader(dbsession, self.app_config) fixtures_loader.loads(self.fixtures) transaction.commit() print("Database initialized.") @@ -90,6 +96,12 @@ def init_database(self, settings): self.engine = get_engine(settings) +class CommandFunctionalTest(FunctionalTest): + + def run_app(self): + self.session = get_tm_session(self.session_factory, transaction.manager) + + class BaseTest(unittest.TestCase): """ Pyramid default test. @@ -99,6 +111,7 @@ class BaseTest(unittest.TestCase): config_section = 'base_test' def setUp(self): + logger._logger.setLevel('WARNING') logger.debug(self, 'Setup Test...') self.settings = plaster.get_settings( self.config_uri, diff --git a/tracim/tests/commands/test_commands.py b/tracim/tests/commands/test_commands.py index e672746..751552c 100644 --- a/tracim/tests/commands/test_commands.py +++ b/tracim/tests/commands/test_commands.py @@ -1,12 +1,25 @@ # -*- coding: utf-8 -*- import os import subprocess - +import pytest import tracim +from tracim.command import TracimCLI +from tracim.exceptions import UserAlreadyExistError +from tracim.exceptions import BadCommandError +from tracim.exceptions import GroupDoesNotExist +from tracim.exceptions import UserDoesNotExist +from tracim.lib.core.user import UserApi +from tracim.tests import CommandFunctionalTest + +class TestCommands(CommandFunctionalTest): + """ + Test tracimcli command line ui. + """ -class TestCommands(object): - def test_commands(self): + config_section = 'app:command_test' + + def test_func__check_commands_list__ok__nominal_case(self) -> None: """ Test listing of tracimcli command: Tracim commands must be listed :return: @@ -20,3 +33,168 @@ def test_commands(self): assert output.find('user update') > 0 assert output.find('db init') > 0 assert output.find('db delete') > 0 + assert output.find('webdav start') > 0 + + def test_func__user_create_command__ok__nominal_case(self) -> None: + """ + Test User creation + """ + api = UserApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + with pytest.raises(UserDoesNotExist): + api.get_one_by_email('command_test@user') + app = TracimCLI() + result = app.run([ + 'user', 'create', + '-c', 'tests_configs.ini#command_test', + '-l', 'command_test@user', + '-p', 'new_password', + '--debug', + ]) + new_user = api.get_one_by_email('command_test@user') + assert new_user.email == 'command_test@user' + assert new_user.validate_password('new_password') + assert new_user.profile.name == 'users' + + def test_func__user_create_command__ok__in_admin_group(self) -> None: + """ + Test User creation with admin as group + """ + api = UserApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + with pytest.raises(UserDoesNotExist): + api.get_one_by_email('command_test@user') + app = TracimCLI() + result = app.run([ + 'user', 'create', + '-c', 'tests_configs.ini#command_test', + '-l', 'command_test@user', + '-p', 'new_password', + '-g', 'administrators', + '--debug', + ]) + new_user = api.get_one_by_email('command_test@user') + assert new_user.email == 'command_test@user' + assert new_user.validate_password('new_password') + assert new_user.profile.name == 'administrators' + + def test_func__user_create_command__err__in_unknown_group(self) -> None: + """ + Test User creation with an unknown group + """ + api = UserApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + app = TracimCLI() + with pytest.raises(GroupDoesNotExist): + result = app.run([ + 'user', 'create', + '-c', 'tests_configs.ini#command_test', + '-l', 'command_test@user', + '-p', 'new_password', + '-g', 'unknown', + '--debug', + ]) + + def test_func__user_create_command__err_user_already_exist(self) -> None: + """ + Test User creation with existing user login + """ + api = UserApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + app = TracimCLI() + with pytest.raises(UserAlreadyExistError): + result = app.run([ + '--debug', + 'user', 'create', + '-c', 'tests_configs.ini#command_test', + '-l', 'admin@admin.admin', + '-p', 'new_password', + '--debug', + ]) + + def test_func__user_create_command__err__password_required(self) -> None: + """ + Test User creation without filling password + """ + api = UserApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + app = TracimCLI() + with pytest.raises(BadCommandError): + result = app.run([ + '--debug', + 'user', 'create', + '-c', 'tests_configs.ini#command_test', + '-l', 'admin@admin.admin', + '--debug', + ]) + + def test_func__user_update_command__ok__nominal_case(self) -> None: + """ + Test user password update + """ + api = UserApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + user = api.get_one_by_email('admin@admin.admin') + assert user.email == 'admin@admin.admin' + assert user.validate_password('admin@admin.admin') + assert not user.validate_password('new_password') + + app = TracimCLI() + result = app.run([ + 'user', 'update', + '-c', 'tests_configs.ini#command_test', + '-l', 'admin@admin.admin', + '-p', 'new_password', + '--debug', + ]) + new_user = api.get_one_by_email('admin@admin.admin') + assert new_user.email == 'admin@admin.admin' + assert new_user.validate_password('new_password') + assert not new_user.validate_password('admin@admin.admin') + + def test_func__user_update_command__ok__remove_group(self) -> None: + """ + Test user password update + """ + api = UserApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + user = api.get_one_by_email('admin@admin.admin') + assert user.email == 'admin@admin.admin' + assert user.validate_password('admin@admin.admin') + assert not user.validate_password('new_password') + assert user.profile.name == 'administrators' + app = TracimCLI() + result = app.run([ + 'user', 'update', + '-c', 'tests_configs.ini#command_test', + '-l', 'admin@admin.admin', + '-p', 'new_password', + '-rmg', 'administrators', + '--debug', + ]) + new_user = api.get_one_by_email('admin@admin.admin') + assert new_user.email == 'admin@admin.admin' + assert new_user.validate_password('new_password') + assert not new_user.validate_password('admin@admin.admin') + assert new_user.profile.name == 'managers' \ No newline at end of file diff --git a/tracim/tests/functional/test_session.py b/tracim/tests/functional/test_session.py index 83a0517..1fb9401 100644 --- a/tracim/tests/functional/test_session.py +++ b/tracim/tests/functional/test_session.py @@ -50,7 +50,6 @@ def test_api__try_login_enpoint__ok_200__nominal_case(self): assert res.json_body['created'] assert res.json_body['is_active'] assert res.json_body['profile'] - assert isinstance(res.json_body['profile']['id'], int) assert res.json_body['profile']['slug'] == 'administrators' assert res.json_body['caldav_url'] is None assert res.json_body['avatar_url'] is None @@ -109,7 +108,6 @@ def test_api__try_whoami_enpoint__ok_200__nominal_case(self): assert res.json_body['created'] assert res.json_body['is_active'] assert res.json_body['profile'] - assert isinstance(res.json_body['profile']['id'], int) assert res.json_body['profile']['slug'] == 'administrators' assert res.json_body['caldav_url'] is None assert res.json_body['avatar_url'] is None diff --git a/tracim/tests/functional/test_workspaces.py b/tracim/tests/functional/test_workspaces.py index 2f61a9e..06a42b9 100644 --- a/tracim/tests/functional/test_workspaces.py +++ b/tracim/tests/functional/test_workspaces.py @@ -156,7 +156,6 @@ def test_api__get_workspace_members__ok_200__nominal_case(self): assert len(res) == 2 user_role = res[0] assert user_role['role_slug'] == 'workspace-manager' - assert user_role['role_id'] == 8 assert user_role['user_id'] == 1 assert user_role['workspace_id'] == 1 assert user_role['user']['display_name'] == 'Global manager' diff --git a/tracim/tests/library/test_content_api.py b/tracim/tests/library/test_content_api.py index 5592e12..b0734d0 100644 --- a/tracim/tests/library/test_content_api.py +++ b/tracim/tests/library/test_content_api.py @@ -213,14 +213,13 @@ def test_archive(self): user = uapi.create_minimal_user( email='this.is@user', groups=groups, - save_now=True + save_now=True, ) workspace_api = WorkspaceApi( current_user=user, session=self.session, - config=self.app_config + config=self.app_config, ) - workspace = workspace_api.create_workspace( 'test workspace', save_now=True diff --git a/tracim/tests/library/test_group_api.py b/tracim/tests/library/test_group_api.py new file mode 100644 index 0000000..329af82 --- /dev/null +++ b/tracim/tests/library/test_group_api.py @@ -0,0 +1,74 @@ +# coding=utf-8 +import pytest + +from tracim.exceptions import GroupDoesNotExist +from tracim.lib.core.group import GroupApi +from tracim.tests import DefaultTest +from tracim.fixtures.users_and_groups import Base as BaseFixture +from tracim.fixtures.content import Content as ContentFixture + + +class TestGroupApi(DefaultTest): + fixtures = [BaseFixture, ContentFixture] + + def test_unit__get_one__ok_nominal_case(self) -> None: + """ + Get one group by id + """ + api = GroupApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + group = api.get_one(1) + assert group.group_id == 1 + assert group.group_name == 'users' + + def test_unit__get_one__err__group_not_exist(self) -> None: + """ + Get one group who does not exist by id + """ + api = GroupApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + with pytest.raises(GroupDoesNotExist): + group = api.get_one(10) + + def test_unit__get_one_group_with_name__nominal_case(self) -> None: + """ + get one group by name + """ + api = GroupApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + group = api.get_one_with_name('administrators') + assert group.group_id == 3 + assert group.group_name == 'administrators' + + def test_unit__get_one_with_name__err__group_not_exist(self) -> None: + """ + get one group by name who does not exist + """ + api = GroupApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + with pytest.raises(GroupDoesNotExist): + group = api.get_one_with_name('unknown_group') + + def test_unit__get_all__ok__nominal_case(self): + """ + get all groups + """ + api = GroupApi( + current_user=None, + session=self.session, + config=self.app_config, + ) + groups = api.get_all() + assert ['users', 'managers', 'administrators'] == [group.group_name for group in groups] # nopep8 diff --git a/tracim/tests/models/test_controller.py b/tracim/tests/models/test_controller.py new file mode 100644 index 0000000..379ce09 --- /dev/null +++ b/tracim/tests/models/test_controller.py @@ -0,0 +1,16 @@ +# coding=utf-8 +import pytest +from pyramid.config import Configurator + +from tracim.views.controllers import Controller + + +class TestControllerModel(object): + """ + Test for Controller object + """ + def test_unit__bind__err__not_implemented(self): + controller = Controller() + configurator = Configurator() + with pytest.raises(NotImplementedError): + controller.bind(configurator) diff --git a/tracim/tests/models/test_permission.py b/tracim/tests/models/test_permission.py new file mode 100644 index 0000000..9af83ec --- /dev/null +++ b/tracim/tests/models/test_permission.py @@ -0,0 +1,51 @@ +# coding=utf-8 +import transaction +from tracim.tests import eq_ +from tracim.tests import BaseTest +from tracim.models.auth import Permission + + +class TestPermissionModel(BaseTest): + """ + Test for permission model + """ + def test_unit__create__ok__nominal_case(self): + self.session.flush() + transaction.commit() + + name = 'my_permission' + description = 'my_perm_description' + permission = Permission() + permission.permission_name = name + permission.description = description + + self.session.add(permission) + self.session.flush() + transaction.commit() + + new_permission = self.session.query(Permission).filter(permission.permission_name == name).one() # nopep8 + + assert new_permission.permission_name == name + assert new_permission.description == description + assert new_permission.permission_id + assert isinstance(new_permission.permission_id, int) + # TODO - G.M -24-05-2018 - Do test for groups + + def test_unit__repr__ok__nominal_case(self): + name = 'my_permission' + description = 'my_perm_description' + permission = Permission() + permission.permission_name = name + permission.description = description + + assert permission.__repr__() == "" + + def test_unit__unicode__ok__nominal_case(self): + name = 'my_permission' + description = 'my_perm_description' + permission = Permission() + permission.permission_name = name + permission.description = description + + assert permission.__unicode__() == name + diff --git a/tracim/tests/models/test_user.py b/tracim/tests/models/test_user.py index 203da70..1e9b080 100644 --- a/tracim/tests/models/test_user.py +++ b/tracim/tests/models/test_user.py @@ -1,15 +1,15 @@ # -*- coding: utf-8 -*- -import transaction -from tracim.tests import eq_ +import transaction from tracim.tests import BaseTest - from tracim.models.auth import User class TestUserModel(BaseTest): - - def test_create(self): + """ + Test for User model + """ + def test_unit__create__ok__nominal_case(self): self.session.flush() transaction.commit() name = 'Damien' @@ -23,13 +23,49 @@ def test_create(self): self.session.flush() transaction.commit() - new_user = self.session.query(User).filter(User.display_name==name).one() + new_user = self.session.query(User).filter(User.display_name == name).one() # nopep8 + + assert new_user.display_name == name + assert new_user.email == email + assert new_user.email_address == email + + def test_unit__password__ok__nominal_case(self): + """ + Check if password can be set and hashed password + can be retrieve. Verify if hashed password is not + same as password. + """ + name = 'Damien' + email = 'tracim@trac.im' + password = 'my_secure_password' + + user = User() + user.display_name = name + user.email = email + assert user._password is None + user.password = password + assert user._password is not None + assert user._password != password + assert user.password == user._password + + def test__unit__validate_password__ok__nominal_case(self): + """ + Check if validate_password can correctly check if password i the correct + one + """ - eq_(new_user.display_name, name) - eq_(new_user.email, email) - eq_(new_user.email_address, email) + name = 'Damien' + email = 'tracim@trac.im' + password = 'my_secure_password' + + user = User() + user.display_name = name + user.email = email + user.password = password + + assert user.validate_password(password) is True - def test_null_password(self): + def test_unit__validate_password__false__null_password(self): # Check bug #70 fixed # http://tracim.org/workspaces/4/folders/5/threads/70 @@ -40,4 +76,49 @@ def test_null_password(self): user.display_name = name user.email = email - eq_(False, user.validate_password(None)) + assert user.validate_password('') is False + + def test_unit__validate_password__false__bad_password(self): + """ + Check if validate_password can correctly check if password is + an uncorrect correct one + """ + name = 'Damien' + email = 'tracim@trac.im' + password = 'my_secure_password' + + user = User() + user.display_name = name + user.email = email + user.password = password + + assert user.validate_password('uncorrect_password') is False + + def test_unit__repr__ok__nominal_case(self): + name = 'Damien' + email = 'tracim@trac.im' + + user = User() + user.display_name = name + user.email = email + + assert user.__repr__() == "" # nopep8 + + def test_unit__unicode__ok__nominal_case(self): + name = 'Damien' + email = 'tracim@trac.im' + + user = User() + user.display_name = name + user.email = email + + assert user.__unicode__() == name + + def test__unit__unicode__ok__no_display_name(self): + + email = 'tracim@trac.im' + + user = User() + user.email = email + + assert user.__unicode__() == email \ No newline at end of file diff --git a/tracim/views/core_api/schemas.py b/tracim/views/core_api/schemas.py index 954e155..eeba02b 100644 --- a/tracim/views/core_api/schemas.py +++ b/tracim/views/core_api/schemas.py @@ -9,44 +9,84 @@ class ProfileSchema(marshmallow.Schema): - id = marshmallow.fields.Int(dump_only=True, validate=OneOf(Profile._IDS)) - slug = marshmallow.fields.String(attribute='name', validate=OneOf(Profile._NAME)) + slug = marshmallow.fields.String( + attribute='name', + validate=OneOf(Profile._NAME), + example='managers', + ) + + class Meta: + description = 'User Profile, give user right on whole Tracim instance.' class UserSchema(marshmallow.Schema): - user_id = marshmallow.fields.Int(dump_only=True) - email = marshmallow.fields.Email(required=True) - display_name = marshmallow.fields.String() - created = marshmallow.fields.DateTime(format='iso8601') - is_active = marshmallow.fields.Bool() + user_id = marshmallow.fields.Int(dump_only=True, example=3) + email = marshmallow.fields.Email( + required=True, + example='suri.cate@algoo.fr' + ) + display_name = marshmallow.fields.String( + example='Suri Cate', + ) + created = marshmallow.fields.DateTime( + format='iso8601', + description='User account creation date (iso8601 format).', + ) + is_active = marshmallow.fields.Bool( + example=True, + # TODO - G.M - Explains this value. + ) # TODO - G.M - 17-04-2018 - Restrict timezone values - timezone = marshmallow.fields.String() + timezone = marshmallow.fields.String( + example="Paris/Europe", + ) # TODO - G.M - 17-04-2018 - check this, relative url allowed ? caldav_url = marshmallow.fields.Url( allow_none=True, relative=True, - attribute='calendar_url' + attribute='calendar_url', + example="/api/v2/calendar/user/3.ics/", + description="The url for calendar CalDAV direct access", + ) + avatar_url = marshmallow.fields.Url( + allow_none=True, + example="/api/v2/assets/avatars/suri-cate.jpg", + description="avatar_url is the url to the image file. " + "If no avatar, then set it to null " + "(and frontend will interpret this with a default avatar)", ) - avatar_url = marshmallow.fields.Url(allow_none=True) profile = marshmallow.fields.Nested( ProfileSchema, many=False, ) + class Meta: + description = 'User account of Tracim' + class UserIdPathSchema(marshmallow.Schema): - user_id = marshmallow.fields.Int() + user_id = marshmallow.fields.Int(example=3) class WorkspaceIdPathSchema(marshmallow.Schema): - workspace_id = marshmallow.fields.Int() + workspace_id = marshmallow.fields.Int(example=4) class BasicAuthSchema(marshmallow.Schema): - email = marshmallow.fields.Email(required=True) - password = marshmallow.fields.String(required=True, load_only=True) + email = marshmallow.fields.Email( + example='suri.cate@algoo.fr', + required=True + ) + password = marshmallow.fields.String( + example='8QLa$