Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
- Bugfix disable possibility to change report's author by Admin user ([#201](https://github.com/Code-Poets/sheetstorm/pull/201))
- Bugfix for access to editing managers list and update tests ([#197](https://github.com/Code-Poets/sheetstorm/pull/197))
- Bugfix show all project list ([#237](https://github.com/Code-Poets/sheetstorm/pull/237))
- Bugfix user birth day has no limit ([#231](https://github.com/Code-Poets/sheetstorm/pull/231))
- Bugfix wrong projects displayed after report creation fail ([#228](https://github.com/Code-Poets/sheetstorm/pull/228))


Expand Down
20 changes: 9 additions & 11 deletions employees/tests/test_unit_report_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,9 @@

class DataSetUpToTests(BaseSerializerTestCase):
serializer_class = ReportSerializer
required_input = {
"date": datetime.datetime.now().date(),
"description": "Some description",
"author": None,
"project": None,
"work_hours": Decimal("8.00"),
}

def setUp(self):

super().setUp()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

self.sample_string_for_type_validation_tests = "This is a string"
author = CustomUser(
email="testuser@codepoets.it", password="newuserpasswd", first_name="John", last_name="Doe", country="PL"
Expand All @@ -43,9 +36,14 @@ def setUp(self):
project.full_clean()
project.save()

self.required_input["author"] = author
self.required_input["project"] = project
self.required_input["task_activities"] = TaskActivityType.objects.get(name="Other")
self.required_input = {
"date": datetime.datetime.now().date(),
"description": "Some description",
"author": author,
"project": project,
"work_hours": Decimal("8.00"),
"task_activities": TaskActivityType.objects.get(name="Other"),
}


class ReportSerializerTests(DataSetUpToTests):
Expand Down
81 changes: 39 additions & 42 deletions users/common/strings.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,47 @@
# pylint: disable=line-too-long
from enum import Enum

from django.utils.translation import ugettext_lazy
from django.utils.translation import ugettext_lazy as _
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 👍 👍


from users.common import constants
from utils.mixins import NotCallableMixin


class ConfirmationMessages:
SUCCESSFUL_UPDATE_USER_MESSAGE = ugettext_lazy("Account has been successfully updated!")
SUCCESSFUL_USER_PASSWORD_CHANGE_MESSAGE = ugettext_lazy("Your password has been successfully updated!")
FAILED_USER_PASSWORD_CHANGE_MESSAGE = ugettext_lazy("Please correct the error below.")
SUCCESSFUL_UPDATE_USER_MESSAGE = _("Account has been successfully updated!")
SUCCESSFUL_USER_PASSWORD_CHANGE_MESSAGE = _("Your password has been successfully updated!")
FAILED_USER_PASSWORD_CHANGE_MESSAGE = _("Please correct the error below.")


class PermissionsMessage:
NONE_ADMIN_USER = ugettext_lazy("You are not allowed to enter - for administration only.")
NONE_ADMIN_OR_OWNER_USER = ugettext_lazy("It's none of your business.")
NONE_ADMIN_USER = _("You are not allowed to enter - for administration only.")
NONE_ADMIN_OR_OWNER_USER = _("It's none of your business.")


class CustomUserAdminText:
PERSONAL_INFO = ugettext_lazy("Personal info")
STATUS = ugettext_lazy("Status")
PERMISSIONS = ugettext_lazy("Permissions")
IMPORTANT_DATES = ugettext_lazy("Important dates")
PERSONAL_INFO = _("Personal info")
STATUS = _("Status")
PERMISSIONS = _("Permissions")
IMPORTANT_DATES = _("Important dates")


class CustomUserModelText:
VERBOSE_NAME_USER = ugettext_lazy("user")
VERBOSE_NAME_PLURAL_USERS = ugettext_lazy("users")

EMAIL_ADDRESS = ugettext_lazy("email address")
FIRST_NAME = ugettext_lazy("first name")
LAST_NAME = ugettext_lazy("last name")
IS_STAFF = ugettext_lazy("staff status")
STAFF_HELP_TEXT = ugettext_lazy("Designates whether the user can log into this admin site.")
IS_ACTIVE = ugettext_lazy("active")
ACTIVE_HELP_TEXT = ugettext_lazy(
VERBOSE_NAME_USER = _("user")
VERBOSE_NAME_PLURAL_USERS = _("users")

EMAIL_ADDRESS = _("email address")
FIRST_NAME = _("first name")
LAST_NAME = _("last name")
IS_STAFF = _("staff status")
STAFF_HELP_TEXT = _("Designates whether the user can log into this admin site.")
IS_ACTIVE = _("active")
ACTIVE_HELP_TEXT = _(
"Designates whether this user should be treated as active. Unselect this instead of deleting accounts."
)
DATE_JOINED = ugettext_lazy("date joined")
DATE_OF_BIRTH = ugettext_lazy("date of birth")
UPDATED_AT = ugettext_lazy("updated at")
PHONE_REGEX_MESSAGE = ugettext_lazy(
"Phone number must be entered in the format: '999999999'. Up to 15 digits allowed."
)
DATE_JOINED = _("date joined")
DATE_OF_BIRTH = _("date of birth")
UPDATED_AT = _("updated at")
PHONE_REGEX_MESSAGE = _("Phone number must be entered in the format: '999999999'. Up to 15 digits allowed.")


class ValidationErrorText:
Expand All @@ -56,28 +54,27 @@ class ValidationErrorText:
"Please enter an e-mail address with a valid domain (" + ", ".join(constants.VALID_EMAIL_DOMAIN_LIST) + ")"
)
VALIDATION_ERROR_EMAIL_MESSAGE_DOMAIN_SHORT = "Please enter an e-mail address with a valid domain"
VALIDATION_ERROR_SIGNUP_EMAIL_MESSAGE = ugettext_lazy("A user is already registered with this e-mail address.")
VALIDATION_ERROR_SIGNUP_PASSWORD_MESSAGE = ugettext_lazy("The two password fields didn't match.")
VALIDATION_ERROR_SIGNUP_EMAIL_MESSAGE = _("A user is already registered with this e-mail address.")
VALIDATION_ERROR_SIGNUP_PASSWORD_MESSAGE = _("The two password fields didn't match.")
VALIDATION_ERROR_AGE_NOT_ACCEPTED = _("User can't be below 18 or above 99 years old.")


class CustomUserCountryText:
POLAND = ugettext_lazy("Poland")
UNITED_STATES = ugettext_lazy("United States")
UNITED_KINGDOM = ugettext_lazy("United Kingdom")
GERMANY = ugettext_lazy("Germany")
FRANCE = ugettext_lazy("France")
POLAND = _("Poland")
UNITED_STATES = _("United States")
UNITED_KINGDOM = _("United Kingdom")
GERMANY = _("Germany")
FRANCE = _("France")


class CustomUserUserTypeText:
EMPLOYEE = ugettext_lazy("Employee")
MANAGER = ugettext_lazy("Manager")
ADMIN = ugettext_lazy("Admin")
EMPLOYEE = _("Employee")
MANAGER = _("Manager")
ADMIN = _("Admin")


class SuccessInfoAfterRegistrationText(NotCallableMixin, Enum):
CONGRATULATIONS = ugettext_lazy("Congratulations!")
ACCOUNT_CREATED = ugettext_lazy("Your account has been successfully created! Now you can sign in!")
REDIRECTION_INFO = ugettext_lazy(
"You will be redirected in few seconds to the login site or press a button to make it faster."
)
OKAY_BUTTON = ugettext_lazy("Okay!")
CONGRATULATIONS = _("Congratulations!")
ACCOUNT_CREATED = _("Your account has been successfully created! Now you can sign in!")
REDIRECTION_INFO = _("You will be redirected in few seconds to the login site or press a button to make it faster.")
OKAY_BUTTON = _("Okay!")
19 changes: 19 additions & 0 deletions users/migrations/0002_auto_20190527_1153.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 2.1.8 on 2019-05-27 11:53

from django.db import migrations, models
import users.validators


class Migration(migrations.Migration):

dependencies = [
('users', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='customuser',
name='date_of_birth',
field=models.DateField(blank=True, null=True, validators=[users.validators.UserAgeValidator(18, 99)], verbose_name='date of birth'),
),
]
8 changes: 7 additions & 1 deletion users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from users.common.strings import ValidationErrorText
from users.common.utils import custom_validate_email_function
from users.common.validators import PhoneRegexValidator
from users.validators import UserAgeValidator

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -85,7 +86,12 @@ class UserType(ChoiceEnum):
CustomUserModelText.IS_ACTIVE, default=True, help_text=CustomUserModelText.ACTIVE_HELP_TEXT
)
date_joined = models.DateTimeField(CustomUserModelText.DATE_JOINED, auto_now_add=True)
date_of_birth = models.DateField(CustomUserModelText.DATE_OF_BIRTH, blank=True, null=True)
date_of_birth = models.DateField(
CustomUserModelText.DATE_OF_BIRTH,
blank=True,
null=True,
validators=[UserAgeValidator(UserAgeValidator.MINIMAL_ACCETABLE_AGLE, UserAgeValidator.MAXIMAL_ACCEPTABLE_AGE)],
)
updated_at = models.DateTimeField(CustomUserModelText.UPDATED_AT, auto_now=True)
phone_number = models.CharField(
validators=[PhoneRegexValidator], max_length=constants.PHONE_NUMBER_MAX_LENGTH, blank=True, null=True
Expand Down
28 changes: 17 additions & 11 deletions users/tests/test_unit_customuser_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.core.exceptions import ValidationError
from django.core.validators import MaxLengthValidator
from django.test import TestCase
from freezegun import freeze_time

from users.common import constants
from users.common.model_helpers import create_user_using_full_clean_and_save
Expand Down Expand Up @@ -117,18 +118,22 @@ def test_that_email_user_should_send_email_to_self_user(self):
self.assertEqual(mocked_method(), "Email has been sent successfully")


@freeze_time("2019-05-27")
class TestCustomUserModelField(BaseModelTestCase):
model_class = CustomUser
required_input = {
"email": "example@codepoets.it",
"first_name": "Jan",
"last_name": "Kowalski",
"date_of_birth": datetime.datetime.now().date(),
"phone_number": "123456789",
"country": "PL",
"user_type": "EMPLOYEE",
"password": "passwduser",
}

def setUp(self):
super().setUp()
self.required_input = {
"email": "example@codepoets.it",
"first_name": "Jan",
"last_name": "Kowalski",
"date_of_birth": datetime.datetime.strptime("2000-05-13", "%Y-%m-%d").date(),
"phone_number": "123456789",
"country": "PL",
"user_type": "EMPLOYEE",
"password": "passwduser",
}

def test_customuser_model_email_field_should_accept_correct_input(self):
self.field_should_accept_input("email", "user@codepoets.it")
Expand Down Expand Up @@ -166,7 +171,8 @@ def test_customuser_model_date_joined_field_should_be_filled_on_save(self):
self.field_should_have_non_null_default("date_joined")

def test_customuser_model_date_of_birth_field_should_accept_correct_input(self):
self.field_should_accept_input("date_of_birth", datetime.datetime.now().date())
date_of_birth = datetime.datetime.strptime("2001-05-26", "%Y-%m-%d").date()
self.field_should_accept_input("date_of_birth", date_of_birth)

def test_customuser_model_date_of_birth_field_may_be_empty(self):
self.field_should_accept_null("date_of_birth")
Expand Down
46 changes: 28 additions & 18 deletions users/tests/test_unit_customuser_serializer.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
import datetime

from freezegun import freeze_time

from users.common import constants
from users.common.model_helpers import create_user_using_full_clean_and_save
from users.serializers import CustomRegisterSerializer
from users.serializers import UserSerializer
from utils.base_tests import BaseSerializerTestCase


@freeze_time("2019-05-23 11:00")
class TestUserSerializerField(BaseSerializerTestCase):
serializer_class = UserSerializer
required_input = {
"email": "example@codepoets.it",
"first_name": "Jan",
"last_name": "Kowalski",
"date_of_birth": datetime.datetime.now().date(),
"phone_number": "123456789",
"country": "PL",
"user_type": "EMPLOYEE",
"password": "passwduser",
}

def setUp(self):
super().setUp()
self.required_input = {
"email": "example@codepoets.it",
"first_name": "Jan",
"last_name": "Kowalski",
"date_of_birth": datetime.datetime.strptime("2001-04-19", "%Y-%m-%d").date(),
"phone_number": "123456789",
"country": "PL",
"user_type": "EMPLOYEE",
"password": "passwduser",
}

def test_user_serializer_email_field_should_accept_correct_input(self):
self.field_should_accept_input("email", "testuser@codepoets.it")
Expand All @@ -41,7 +47,8 @@ def test_user_serializer_last_name_field_should_not_accept_string_longer_than_se
self.field_should_not_accept_input("last_name", "a" * (constants.LAST_NAME_MAX_LENGTH + 1))

def test_user_serializer_date_of_birth_field_should_accept_correct_input(self):
self.field_should_accept_input("date_of_birth", datetime.datetime.now().date())
date_of_birth = datetime.datetime.strptime("2001-04-19", "%Y-%m-%d").date()
self.field_should_accept_input("date_of_birth", date_of_birth)

def test_user_serializer_date_of_birth_field_may_be_empty(self):
self.field_should_accept_null("date_of_birth")
Expand Down Expand Up @@ -70,13 +77,16 @@ def test_user_serializer_password_field_should_accept_correct_input(self):

class TestCustomRegisterSerializerField(BaseSerializerTestCase):
serializer_class = CustomRegisterSerializer
required_input = {
"email": "example@codepoets.it",
"first_name": "Jan",
"last_name": "Kowalski",
"password": "passwduser",
"password_confirmation": "passwduser",
}

def setUp(self):
super().setUp()
self.required_input = {
"email": "example@codepoets.it",
"first_name": "Jan",
"last_name": "Kowalski",
"password": "passwduser",
"password_confirmation": "passwduser",
}

def test_register_serializer_email_field_should_accept_correct_input(self):
self.field_should_accept_input("email", "testuser@codepoets.it")
Expand Down
46 changes: 46 additions & 0 deletions users/tests/test_unit_validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import datetime

from django.core.exceptions import ValidationError
from django.test import TestCase
from freezegun import freeze_time

from users.validators import UserAgeValidator


@freeze_time("2019-05-27")
class TestUserAgeValidator(TestCase):
def setUp(self):
self.user_age_validator = UserAgeValidator(
UserAgeValidator.MINIMAL_ACCETABLE_AGLE, UserAgeValidator.MAXIMAL_ACCEPTABLE_AGE
)

def test_that_users_age_can_be_none(self):
self._assert_date_of_birth_is_valid(None)

def test_that_users_age_can_be_equal_to_lower_limit(self):
# user is exactly 18 years old
date_of_birth = datetime.datetime.strptime("2001-05-27", "%Y-%m-%d").date()
self._assert_date_of_birth_is_valid(date_of_birth)

def test_that_users_age_can_be_equal_to_upper_limit(self):
# user is exactly 100 years old - 1 day (still 99)
date_of_birth = datetime.datetime.strptime("1919-05-28", "%Y-%m-%d").date()
self._assert_date_of_birth_is_valid(date_of_birth)

def test_that_when_users_age_is_below_lower_limit_validation_error_is_raised(self):
# user is exactly 18 years old - 1 day (still 17)
date_of_birth = datetime.datetime.strptime("2001-05-28", "%Y-%m-%d").date()
with self.assertRaises(ValidationError):
self.user_age_validator(date_of_birth)

def test_that_when_users_age_is_above_upper_limit_validation_error_is_raised(self):
# user is exactly 100 years old
date_of_birth = datetime.datetime.strptime("1919-05-27", "%Y-%m-%d").date()
with self.assertRaises(ValidationError):
self.user_age_validator(date_of_birth)

def _assert_date_of_birth_is_valid(self, date_of_birth):
try:
self.user_age_validator(date_of_birth)
except Exception as e: # pylint:disable=broad-except
self.fail(f"Unexpected exception {str(e)} has occurred!")
Loading