Merge pull request #807 from taigaio/generate-api-doc

Fix small bugs found while generating api documentation
remotes/origin/issue/4795/notification_even_they_are_disabled
David Barragán Merino 2016-08-17 11:48:38 +02:00 committed by GitHub
commit 82657f51d3
8 changed files with 39 additions and 36 deletions

View File

@ -12,6 +12,7 @@ before_install:
- sudo /etc/init.d/postgresql stop - sudo /etc/init.d/postgresql stop
- sudo apt-get install -y postgresql-9.4 - sudo apt-get install -y postgresql-9.4
- sudo apt-get install -y postgresql-plpython-9.4 - sudo apt-get install -y postgresql-plpython-9.4
- sudo /etc/init.d/postgresql start
- psql -c 'create database taiga;' -U postgres - psql -c 'create database taiga;' -U postgres
install: install:
- travis_retry pip install -r requirements-devel.txt - travis_retry pip install -r requirements-devel.txt

View File

@ -613,6 +613,8 @@ class ChoiceField(WritableField):
def validate_user_email_allowed_domains(value): def validate_user_email_allowed_domains(value):
validators.validate_email(value)
domain_name = value.split("@")[1] domain_name = value.split("@")[1]
if settings.USER_EMAIL_ALLOWED_DOMAINS and domain_name not in settings.USER_EMAIL_ALLOWED_DOMAINS: 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 = { default_error_messages = {
"invalid": _("Enter a valid email address."), "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): def from_native(self, value):
ret = super(EmailField, self).from_native(value) ret = super(EmailField, self).from_native(value)

View File

@ -65,6 +65,9 @@ class BaseAttachmentViewSet(HistoryResourceMixin, WatchedResourceMixin,
obj.size = obj.attached_file.size obj.size = obj.attached_file.size
obj.name = path.basename(obj.attached_file.name) 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: if obj.project_id != obj.content_object.project_id:
raise exc.WrongArguments(_("Project ID not matches between object and project")) raise exc.WrongArguments(_("Project ID not matches between object and project"))

View File

@ -16,7 +16,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import random
import datetime import datetime
from os import path from os import path
from hashlib import sha1 from hashlib import sha1
@ -33,6 +32,7 @@ from sampledatahelper.helper import SampleDataHelper
from taiga.users.models import * from taiga.users.models import *
from taiga.permissions.choices import ANON_PERMISSIONS from taiga.permissions.choices import ANON_PERMISSIONS
from taiga.projects.choices import BLOCKED_BY_STAFF from taiga.projects.choices import BLOCKED_BY_STAFF
from taiga.external_apps.models import Application, ApplicationToken
from taiga.projects.models import * from taiga.projects.models import *
from taiga.projects.milestones.models import * from taiga.projects.milestones.models import *
from taiga.projects.notifications.choices import NotifyLevel 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_USS_BACK = getattr(settings, "SAMPLE_DATA_NUM_USS_BACK", (8, 20))
NUM_ISSUES = getattr(settings, "SAMPLE_DATA_NUM_ISSUES", (12, 25)) NUM_ISSUES = getattr(settings, "SAMPLE_DATA_NUM_ISSUES", (12, 25))
NUM_WIKI_LINKS = getattr(settings, "SAMPLE_DATA_NUM_WIKI_LINKS", (0, 15)) 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_LIKES = getattr(settings, "SAMPLE_DATA_NUM_LIKES", (0, 10))
NUM_VOTES = getattr(settings, "SAMPLE_DATA_NUM_VOTES", (0, 10)) NUM_VOTES = getattr(settings, "SAMPLE_DATA_NUM_VOTES", (0, 10))
NUM_WATCHERS = getattr(settings, "SAMPLE_DATA_NUM_PROJECT_WATCHERS", (0, 8)) 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] FEATURED_PROJECTS_POSITIONS = [0, 1, 2]
LOOKING_FOR_PEOPLE_PROJECTS_POSITIONS = [0, 1, 2] LOOKING_FOR_PEOPLE_PROJECTS_POSITIONS = [0, 1, 2]
@ -181,36 +183,33 @@ class Command(BaseCommand):
project=project, project=project,
role=role, role=role,
is_admin=self.sd.boolean(), is_admin=self.sd.boolean(),
token=''.join(random.sample('abcdef0123456789', 10))) token=self.sd.hex_chars(10,10))
if role.computable: if role.computable:
computable_project_roles.add(role) computable_project_roles.add(role)
# added custom attributes # added custom attributes
if self.sd.boolean: names = set([self.sd.words(1, 3) for i in range(1, 6)])
names = set([self.sd.words(1, 3) for i in range(1, 6)]) for name in names:
for name in names: UserStoryCustomAttribute.objects.create(name=name,
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,
description=self.sd.words(3, 12), description=self.sd.words(3, 12),
type=self.sd.choice(TYPES_CHOICES)[0], type=self.sd.choice(TYPES_CHOICES)[0],
project=project, project=project,
order=i) 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 the project isn't empty
if x not in empty_projects_range: if x not in empty_projects_range:
@ -272,6 +271,7 @@ class Command(BaseCommand):
self.create_likes(project) self.create_likes(project)
def create_attachment(self, obj, order): def create_attachment(self, obj, order):
attached_file = self.sd.file_from_directory(*ATTACHMENT_SAMPLE_DATA) attached_file = self.sd.file_from_directory(*ATTACHMENT_SAMPLE_DATA)
membership = self.sd.db_object_from_queryset(obj.project.memberships membership = self.sd.db_object_from_queryset(obj.project.memberships
@ -347,7 +347,7 @@ class Command(BaseCommand):
bug.save() bug.save()
custom_attributes_values = {str(ca.id): self.get_custom_attributes_value(ca.type) for ca 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: if custom_attributes_values:
bug.custom_attributes_values.attributes_values = custom_attributes_values bug.custom_attributes_values.attributes_values = custom_attributes_values
bug.custom_attributes_values.save() bug.custom_attributes_values.save()
@ -399,7 +399,7 @@ class Command(BaseCommand):
task.save() task.save()
custom_attributes_values = {str(ca.id): self.get_custom_attributes_value(ca.type) for ca 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: if custom_attributes_values:
task.custom_attributes_values.attributes_values = custom_attributes_values task.custom_attributes_values.attributes_values = custom_attributes_values
task.custom_attributes_values.save() task.custom_attributes_values.save()
@ -447,7 +447,7 @@ class Command(BaseCommand):
us.save() us.save()
custom_attributes_values = {str(ca.id): self.get_custom_attributes_value(ca.type) for ca 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: if custom_attributes_values:
us.custom_attributes_values.attributes_values = custom_attributes_values us.custom_attributes_values.attributes_values = custom_attributes_values
us.custom_attributes_values.save() us.custom_attributes_values.save()
@ -503,7 +503,7 @@ class Command(BaseCommand):
project = Project.objects.create(slug='project-%s'%(counter), project = Project.objects.create(slug='project-%s'%(counter),
name='Project Example {0}'.format(counter), name='Project Example {0}'.format(counter),
description='Project example {0} description'.format(counter), description='Project example {0} description'.format(counter),
owner=random.choice(self.users), owner=self.sd.choice(self.users),
is_private=is_private, is_private=is_private,
anon_permissions=anon_permissions, anon_permissions=anon_permissions,
public_permissions=public_permissions, public_permissions=public_permissions,
@ -533,7 +533,7 @@ class Command(BaseCommand):
user = User.objects.create(username=username, user = User.objects.create(username=username,
full_name=full_name, full_name=full_name,
email=email, email=email,
token=''.join(random.sample('abcdef0123456789', 10)), token=self.sd.hex_chars(10,10),
color=self.sd.choice(COLOR_CHOICES)) color=self.sd.choice(COLOR_CHOICES))
user.set_password('123123') user.set_password('123123')

View File

@ -180,6 +180,7 @@ class Project(ProjectDefaults, TaggedMixin, TagsColorsdMixin, models.Model):
creation_template = models.ForeignKey("projects.ProjectTemplate", creation_template = models.ForeignKey("projects.ProjectTemplate",
related_name="projects", null=True, related_name="projects", null=True,
on_delete=models.SET_NULL,
blank=True, default=None, blank=True, default=None,
verbose_name=_("creation template")) verbose_name=_("creation template"))

View File

@ -21,9 +21,7 @@ from django.db.models import Q
from taiga.base.api import ModelCrudViewSet from taiga.base.api import ModelCrudViewSet
from taiga.projects.notifications.choices import NotifyLevel from taiga.projects.notifications.choices import NotifyLevel
from taiga.projects.notifications.models import Watched
from taiga.projects.models import Project from taiga.projects.models import Project
from taiga.users import services as user_services
from . import serializers from . import serializers
from . import models from . import models
from . import permissions from . import permissions

View File

@ -16,11 +16,10 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.apps import apps
from taiga.base.filters import PermissionBasedFilterBackend from taiga.base.filters import PermissionBasedFilterBackend
from . import services from . import services
class ContactsFilterBackend(PermissionBasedFilterBackend): class ContactsFilterBackend(PermissionBasedFilterBackend):
def filter_queryset(self, user, request, queryset, view): def filter_queryset(self, user, request, queryset, view):
qs = queryset.filter(is_active=True) qs = queryset.filter(is_active=True)

View File

@ -24,10 +24,9 @@ from taiga.base.fields import Field, MethodField, I18NField
from taiga.base.utils.thumbnails import get_thumbnail_url from taiga.base.utils.thumbnails import get_thumbnail_url
from taiga.projects.models import Project 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.gravatar import get_user_gravatar_id
from taiga.users.models import User from taiga.users.models import User
from collections import namedtuple
###################################################### ######################################################
@ -142,7 +141,7 @@ class RoleSerializer(serializers.LightSerializer):
project = Field(attr="project_id") project = Field(attr="project_id")
order = Field() order = Field()
computable = Field() computable = Field()
permissions = Field() permissions = Field()
members_count = MethodField() members_count = MethodField()
def get_members_count(self, obj): def get_members_count(self, obj):