From a6f5b4c0ec7aca3587da79654f2fecb45c8f8c78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Tue, 2 Aug 2016 15:50:54 +0200 Subject: [PATCH 1/2] Fix small bugs found while generating api documentation --- .travis.yml | 1 + taiga/base/api/fields.py | 4 +- taiga/projects/attachments/api.py | 3 ++ .../management/commands/sample_data.py | 50 +++++++++---------- taiga/projects/models.py | 1 + taiga/projects/notifications/api.py | 2 - taiga/users/serializers.py | 5 +- 7 files changed, 35 insertions(+), 31 deletions(-) diff --git a/.travis.yml b/.travis.yml index e07f042c..2fb3d0b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ before_install: - sudo /etc/init.d/postgresql stop - sudo apt-get install -y postgresql-9.4 - sudo apt-get install -y postgresql-plpython-9.4 + - sudo /etc/init.d/postgresql start - psql -c 'create database taiga;' -U postgres install: - travis_retry pip install -r requirements-devel.txt diff --git a/taiga/base/api/fields.py b/taiga/base/api/fields.py index a7efeadf..bab90160 100644 --- a/taiga/base/api/fields.py +++ b/taiga/base/api/fields.py @@ -613,6 +613,8 @@ class ChoiceField(WritableField): def validate_user_email_allowed_domains(value): + validators.validate_email(value) + domain_name = value.split("@")[1] if settings.USER_EMAIL_ALLOWED_DOMAINS and domain_name not in settings.USER_EMAIL_ALLOWED_DOMAINS: @@ -627,7 +629,7 @@ class EmailField(CharField): default_error_messages = { "invalid": _("Enter a valid email address."), } - default_validators = [validators.validate_email, validate_user_email_allowed_domains] + default_validators = [validate_user_email_allowed_domains] def from_native(self, value): ret = super(EmailField, self).from_native(value) diff --git a/taiga/projects/attachments/api.py b/taiga/projects/attachments/api.py index 986c8f19..f2a023c5 100644 --- a/taiga/projects/attachments/api.py +++ b/taiga/projects/attachments/api.py @@ -65,6 +65,9 @@ class BaseAttachmentViewSet(HistoryResourceMixin, WatchedResourceMixin, obj.size = obj.attached_file.size obj.name = path.basename(obj.attached_file.name) + if obj.content_object is None: + raise exc.WrongArguments(_("Object id issue isn't exists")) + if obj.project_id != obj.content_object.project_id: raise exc.WrongArguments(_("Project ID not matches between object and project")) diff --git a/taiga/projects/management/commands/sample_data.py b/taiga/projects/management/commands/sample_data.py index 23bbf598..f474de86 100644 --- a/taiga/projects/management/commands/sample_data.py +++ b/taiga/projects/management/commands/sample_data.py @@ -16,7 +16,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import random import datetime from os import path from hashlib import sha1 @@ -33,6 +32,7 @@ from sampledatahelper.helper import SampleDataHelper from taiga.users.models import * from taiga.permissions.choices import ANON_PERMISSIONS from taiga.projects.choices import BLOCKED_BY_STAFF +from taiga.external_apps.models import Application, ApplicationToken from taiga.projects.models import * from taiga.projects.milestones.models import * from taiga.projects.notifications.choices import NotifyLevel @@ -115,10 +115,12 @@ NUM_TASKS = getattr(settings, "SAMPLE_DATA_NUM_TASKS", (0, 4)) NUM_USS_BACK = getattr(settings, "SAMPLE_DATA_NUM_USS_BACK", (8, 20)) NUM_ISSUES = getattr(settings, "SAMPLE_DATA_NUM_ISSUES", (12, 25)) NUM_WIKI_LINKS = getattr(settings, "SAMPLE_DATA_NUM_WIKI_LINKS", (0, 15)) -NUM_ATTACHMENTS = getattr(settings, "SAMPLE_DATA_NUM_ATTACHMENTS", (0, 4)) +NUM_ATTACHMENTS = getattr(settings, "SAMPLE_DATA_NUM_ATTACHMENTS", (1, 4)) NUM_LIKES = getattr(settings, "SAMPLE_DATA_NUM_LIKES", (0, 10)) NUM_VOTES = getattr(settings, "SAMPLE_DATA_NUM_VOTES", (0, 10)) NUM_WATCHERS = getattr(settings, "SAMPLE_DATA_NUM_PROJECT_WATCHERS", (0, 8)) +NUM_APPLICATIONS = getattr(settings, "SAMPLE_DATA_NUM_APPLICATIONS", (1, 3)) +NUM_APPLICATIONS_TOKENS = getattr(settings, "SAMPLE_DATA_NUM_APPLICATIONS_TOKENS", (1, 3)) FEATURED_PROJECTS_POSITIONS = [0, 1, 2] LOOKING_FOR_PEOPLE_PROJECTS_POSITIONS = [0, 1, 2] @@ -181,36 +183,33 @@ class Command(BaseCommand): project=project, role=role, is_admin=self.sd.boolean(), - token=''.join(random.sample('abcdef0123456789', 10))) + token=self.sd.hex_chars(10,10)) if role.computable: computable_project_roles.add(role) # added custom attributes - if self.sd.boolean: - names = set([self.sd.words(1, 3) for i in range(1, 6)]) - for name in names: - UserStoryCustomAttribute.objects.create(name=name, - description=self.sd.words(3, 12), - type=self.sd.choice(TYPES_CHOICES)[0], - project=project, - order=i) - if self.sd.boolean: - names = set([self.sd.words(1, 3) for i in range(1, 6)]) - for name in names: - TaskCustomAttribute.objects.create(name=name, - description=self.sd.words(3, 12), - type=self.sd.choice(TYPES_CHOICES)[0], - project=project, - order=i) - if self.sd.boolean: - names = set([self.sd.words(1, 3) for i in range(1, 6)]) - for name in names: - IssueCustomAttribute.objects.create(name=name, + names = set([self.sd.words(1, 3) for i in range(1, 6)]) + for name in names: + UserStoryCustomAttribute.objects.create(name=name, description=self.sd.words(3, 12), type=self.sd.choice(TYPES_CHOICES)[0], project=project, order=i) + names = set([self.sd.words(1, 3) for i in range(1, 6)]) + for name in names: + TaskCustomAttribute.objects.create(name=name, + description=self.sd.words(3, 12), + type=self.sd.choice(TYPES_CHOICES)[0], + project=project, + order=i) + names = set([self.sd.words(1, 3) for i in range(1, 6)]) + for name in names: + IssueCustomAttribute.objects.create(name=name, + description=self.sd.words(3, 12), + type=self.sd.choice(TYPES_CHOICES)[0], + project=project, + order=i) # If the project isn't empty if x not in empty_projects_range: @@ -272,6 +271,7 @@ class Command(BaseCommand): self.create_likes(project) + def create_attachment(self, obj, order): attached_file = self.sd.file_from_directory(*ATTACHMENT_SAMPLE_DATA) membership = self.sd.db_object_from_queryset(obj.project.memberships @@ -503,7 +503,7 @@ class Command(BaseCommand): project = Project.objects.create(slug='project-%s'%(counter), name='Project Example {0}'.format(counter), description='Project example {0} description'.format(counter), - owner=random.choice(self.users), + owner=self.sd.choice(self.users), is_private=is_private, anon_permissions=anon_permissions, public_permissions=public_permissions, @@ -533,7 +533,7 @@ class Command(BaseCommand): user = User.objects.create(username=username, full_name=full_name, email=email, - token=''.join(random.sample('abcdef0123456789', 10)), + token=self.sd.hex_chars(10,10), color=self.sd.choice(COLOR_CHOICES)) user.set_password('123123') diff --git a/taiga/projects/models.py b/taiga/projects/models.py index 2c0f4027..7b3c218d 100644 --- a/taiga/projects/models.py +++ b/taiga/projects/models.py @@ -180,6 +180,7 @@ class Project(ProjectDefaults, TaggedMixin, TagsColorsdMixin, models.Model): creation_template = models.ForeignKey("projects.ProjectTemplate", related_name="projects", null=True, + on_delete=models.SET_NULL, blank=True, default=None, verbose_name=_("creation template")) diff --git a/taiga/projects/notifications/api.py b/taiga/projects/notifications/api.py index cd8f564e..9936ae52 100644 --- a/taiga/projects/notifications/api.py +++ b/taiga/projects/notifications/api.py @@ -21,9 +21,7 @@ from django.db.models import Q from taiga.base.api import ModelCrudViewSet from taiga.projects.notifications.choices import NotifyLevel -from taiga.projects.notifications.models import Watched from taiga.projects.models import Project -from taiga.users import services as user_services from . import serializers from . import models from . import permissions diff --git a/taiga/users/serializers.py b/taiga/users/serializers.py index e2e55ea9..a720e46e 100644 --- a/taiga/users/serializers.py +++ b/taiga/users/serializers.py @@ -24,10 +24,9 @@ from taiga.base.fields import Field, MethodField, I18NField from taiga.base.utils.thumbnails import get_thumbnail_url from taiga.projects.models import Project -from .services import get_user_photo_url, get_big_photo_url, get_user_big_photo_url +from .services import get_user_photo_url, get_user_big_photo_url from taiga.users.gravatar import get_user_gravatar_id from taiga.users.models import User -from collections import namedtuple ###################################################### @@ -142,7 +141,7 @@ class RoleSerializer(serializers.LightSerializer): project = Field(attr="project_id") order = Field() computable = Field() - permissions = Field() + permissions = Field() members_count = MethodField() def get_members_count(self, obj): From 0e125d73429803835c80589f0310d246edfc9731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Fri, 12 Aug 2016 10:11:21 +0200 Subject: [PATCH 2/2] Fix sample data to generate alwais the same data --- taiga/projects/management/commands/sample_data.py | 6 +++--- taiga/users/filters.py | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/taiga/projects/management/commands/sample_data.py b/taiga/projects/management/commands/sample_data.py index f474de86..7ced0599 100644 --- a/taiga/projects/management/commands/sample_data.py +++ b/taiga/projects/management/commands/sample_data.py @@ -347,7 +347,7 @@ class Command(BaseCommand): bug.save() custom_attributes_values = {str(ca.id): self.get_custom_attributes_value(ca.type) for ca - in project.issuecustomattributes.all() if self.sd.boolean()} + in project.issuecustomattributes.all().order_by('id') if self.sd.boolean()} if custom_attributes_values: bug.custom_attributes_values.attributes_values = custom_attributes_values bug.custom_attributes_values.save() @@ -399,7 +399,7 @@ class Command(BaseCommand): task.save() custom_attributes_values = {str(ca.id): self.get_custom_attributes_value(ca.type) for ca - in project.taskcustomattributes.all() if self.sd.boolean()} + in project.taskcustomattributes.all().order_by('id') if self.sd.boolean()} if custom_attributes_values: task.custom_attributes_values.attributes_values = custom_attributes_values task.custom_attributes_values.save() @@ -447,7 +447,7 @@ class Command(BaseCommand): us.save() custom_attributes_values = {str(ca.id): self.get_custom_attributes_value(ca.type) for ca - in project.userstorycustomattributes.all() if self.sd.boolean()} + in project.userstorycustomattributes.all().order_by('id') if self.sd.boolean()} if custom_attributes_values: us.custom_attributes_values.attributes_values = custom_attributes_values us.custom_attributes_values.save() diff --git a/taiga/users/filters.py b/taiga/users/filters.py index 4e4dc116..46dd88ac 100644 --- a/taiga/users/filters.py +++ b/taiga/users/filters.py @@ -16,11 +16,10 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.apps import apps - from taiga.base.filters import PermissionBasedFilterBackend from . import services + class ContactsFilterBackend(PermissionBasedFilterBackend): def filter_queryset(self, user, request, queryset, view): qs = queryset.filter(is_active=True)