Merge pull request #609 from taigaio/status-and-default_status-can-be-None

Status and default status can be None
remotes/origin/issue/4795/notification_even_they_are_disabled
David Barragán Merino 2016-02-10 20:45:54 +01:00
commit 010fcfa635
13 changed files with 64 additions and 13 deletions

View File

@ -266,7 +266,7 @@ def userstory_freezer(us) -> dict:
snapshot = { snapshot = {
"ref": us.ref, "ref": us.ref,
"owner": us.owner_id, "owner": us.owner_id,
"status": us.status_id, "status": us.status.id if us.status else None,
"is_closed": us.is_closed, "is_closed": us.is_closed,
"finish_date": str(us.finish_date), "finish_date": str(us.finish_date),
"backlog_order": us.backlog_order, "backlog_order": us.backlog_order,
@ -297,7 +297,7 @@ def issue_freezer(issue) -> dict:
snapshot = { snapshot = {
"ref": issue.ref, "ref": issue.ref,
"owner": issue.owner_id, "owner": issue.owner_id,
"status": issue.status_id, "status": issue.status.id if issue.status else None,
"priority": issue.priority_id, "priority": issue.priority_id,
"severity": issue.severity_id, "severity": issue.severity_id,
"type": issue.type_id, "type": issue.type_id,
@ -321,7 +321,7 @@ def task_freezer(task) -> dict:
snapshot = { snapshot = {
"ref": task.ref, "ref": task.ref,
"owner": task.owner_id, "owner": task.owner_id,
"status": task.status_id, "status": task.status.id if task.status else None,
"milestone": task.milestone_id, "milestone": task.milestone_id,
"subject": task.subject, "subject": task.subject,
"description": task.description, "description": task.description,

View File

@ -98,4 +98,4 @@ class Issue(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, models.
@property @property
def is_closed(self): def is_closed(self):
return self.status.is_closed return self.status is not None and self.status.is_closed

View File

@ -117,7 +117,7 @@ def issues_to_csv(project, queryset):
"owner_full_name": issue.owner.get_full_name() if issue.owner else None, "owner_full_name": issue.owner.get_full_name() if issue.owner else None,
"assigned_to": issue.assigned_to.username if issue.assigned_to else None, "assigned_to": issue.assigned_to.username if issue.assigned_to else None,
"assigned_to_full_name": issue.assigned_to.get_full_name() if issue.assigned_to else None, "assigned_to_full_name": issue.assigned_to.get_full_name() if issue.assigned_to else None,
"status": issue.status.name, "status": issue.status.name if issue.status else None,
"severity": issue.severity.name, "severity": issue.severity.name,
"priority": issue.priority.name, "priority": issue.priority.name,
"type": issue.type.name, "type": issue.type.name,

View File

@ -23,6 +23,8 @@ from django.utils import timezone
#################################### ####################################
def set_finished_date_when_edit_issue(sender, instance, **kwargs): def set_finished_date_when_edit_issue(sender, instance, **kwargs):
if instance.status is None:
return
if instance.status.is_closed and not instance.finished_date: if instance.status.is_closed and not instance.finished_date:
instance.finished_date = timezone.now() instance.finished_date = timezone.now()
elif not instance.status.is_closed and instance.finished_date: elif not instance.status.is_closed and instance.finished_date:

View File

@ -23,7 +23,7 @@ from . import models
def calculate_milestone_is_closed(milestone): def calculate_milestone_is_closed(milestone):
return (milestone.user_stories.all().count() > 0 and return (milestone.user_stories.all().count() > 0 and
all([task.status.is_closed for task in milestone.tasks.all()]) and all([task.status is not None and task.status.is_closed for task in milestone.tasks.all()]) and
all([user_story.is_closed for user_story in milestone.user_stories.all()])) all([user_story.is_closed for user_story in milestone.user_stories.all()]))

View File

@ -84,7 +84,7 @@ def get_stats_for_project_issues(project):
) )
for issue in issues: for issue in issues:
project_issues_stats['total_issues'] += 1 project_issues_stats['total_issues'] += 1
if issue.status.is_closed: if issue.status is not None and issue.status.is_closed:
project_issues_stats['closed_issues'] += 1 project_issues_stats['closed_issues'] += 1
else: else:
project_issues_stats['opened_issues'] += 1 project_issues_stats['opened_issues'] += 1

View File

@ -68,7 +68,7 @@ class TaskSerializer(WatchersValidator, VoteResourceSerializerMixin, EditableWat
return mdrender(obj.project, obj.description) return mdrender(obj.project, obj.description)
def get_is_closed(self, obj): def get_is_closed(self, obj):
return obj.status.is_closed return obj.status is not None and obj.status.is_closed
class TaskListSerializer(TaskSerializer): class TaskListSerializer(TaskSerializer):

View File

@ -129,9 +129,9 @@ def tasks_to_csv(project, queryset):
"owner_full_name": task.owner.get_full_name() if task.owner else None, "owner_full_name": task.owner.get_full_name() if task.owner else None,
"assigned_to": task.assigned_to.username if task.assigned_to else None, "assigned_to": task.assigned_to.username if task.assigned_to else None,
"assigned_to_full_name": task.assigned_to.get_full_name() if task.assigned_to else None, "assigned_to_full_name": task.assigned_to.get_full_name() if task.assigned_to else None,
"status": task.status.name, "status": task.status.name if task.status else None,
"is_iocaine": task.is_iocaine, "is_iocaine": task.is_iocaine,
"is_closed": task.status.is_closed, "is_closed": task.status is not None and task.status.is_closed,
"us_order": task.us_order, "us_order": task.us_order,
"taskboard_order": task.taskboard_order, "taskboard_order": task.taskboard_order,
"attachments": task.attachments.count(), "attachments": task.attachments.count(),

View File

@ -100,6 +100,8 @@ def _try_to_close_milestone_when_delete_task(instance):
#################################### ####################################
def set_finished_date_when_edit_task(sender, instance, **kwargs): def set_finished_date_when_edit_task(sender, instance, **kwargs):
if instance.status is None:
return
if instance.status.is_closed and not instance.finished_date: if instance.status.is_closed and not instance.finished_date:
instance.finished_date = timezone.now() instance.finished_date = timezone.now()
elif not instance.status.is_closed and instance.finished_date: elif not instance.status.is_closed and instance.finished_date:

View File

@ -106,9 +106,9 @@ def calculate_userstory_is_closed(user_story):
return False return False
if user_story.tasks.count() == 0: if user_story.tasks.count() == 0:
return user_story.status.is_closed return user_story.status is not None and user_story.status.is_closed
if all([task.status.is_closed for task in user_story.tasks.all()]): if all([task.status is not None and task.status.is_closed for task in user_story.tasks.all()]):
return True return True
return False return False
@ -179,7 +179,7 @@ def userstories_to_csv(project,queryset):
"owner_full_name": us.owner.get_full_name() if us.owner else None, "owner_full_name": us.owner.get_full_name() if us.owner else None,
"assigned_to": us.assigned_to.username if us.assigned_to else None, "assigned_to": us.assigned_to.username if us.assigned_to else None,
"assigned_to_full_name": us.assigned_to.get_full_name() if us.assigned_to else None, "assigned_to_full_name": us.assigned_to.get_full_name() if us.assigned_to else None,
"status": us.status.name, "status": us.status.name if us.status else None,
"is_closed": us.is_closed, "is_closed": us.is_closed,
"backlog_order": us.backlog_order, "backlog_order": us.backlog_order,
"sprint_order": us.sprint_order, "sprint_order": us.sprint_order,

View File

@ -71,6 +71,27 @@ def test_create_issue_without_status(client):
assert response.data['type'] == project.default_issue_type.id assert response.data['type'] == project.default_issue_type.id
def test_create_issue_without_status_in_project_without_default_values(client):
user = f.UserFactory.create()
project = f.ProjectFactory.create(owner=user,
default_issue_status=None,
default_priority=None,
default_severity=None,
default_issue_type = None)
f.MembershipFactory.create(project=project, user=user, is_owner=True)
url = reverse("issues-list")
data = {"subject": "Test user story", "project": project.id}
client.login(user)
response = client.json.post(url, json.dumps(data))
assert response.status_code == 201
assert response.data['status'] == None
assert response.data['severity'] == None
assert response.data['priority'] == None
assert response.data['type'] == None
def test_api_create_issues_in_bulk(client): def test_api_create_issues_in_bulk(client):
project = f.create_project() project = f.create_project()
f.MembershipFactory(project=project, user=project.owner, is_owner=True) f.MembershipFactory(project=project, user=project.owner, is_owner=True)

View File

@ -53,6 +53,19 @@ def test_create_task_without_status(client):
assert response.data['status'] == project.default_task_status.id assert response.data['status'] == project.default_task_status.id
def test_create_task_without_default_values(client):
user = f.UserFactory.create()
project = f.ProjectFactory.create(owner=user, default_task_status=None)
f.MembershipFactory.create(project=project, user=user, is_owner=True)
url = reverse("tasks-list")
data = {"subject": "Test user story", "project": project.id}
client.login(user)
response = client.json.post(url, json.dumps(data))
assert response.status_code == 201
assert response.data['status'] == None
def test_api_update_task_tags(client): def test_api_update_task_tags(client):
project = f.ProjectFactory.create() project = f.ProjectFactory.create()
task = f.create_task(project=project, status__project=project, milestone=None, user_story=None) task = f.create_task(project=project, status__project=project, milestone=None, user_story=None)

View File

@ -79,6 +79,19 @@ def test_create_userstory_without_status(client):
assert response.data['status'] == project.default_us_status.id assert response.data['status'] == project.default_us_status.id
def test_create_userstory_without_default_values(client):
user = f.UserFactory.create()
project = f.ProjectFactory.create(owner=user, default_us_status=None)
f.MembershipFactory.create(project=project, user=user, is_owner=True)
url = reverse("userstories-list")
data = {"subject": "Test user story", "project": project.id}
client.login(user)
response = client.json.post(url, json.dumps(data))
assert response.status_code == 201
assert response.data['status'] == None
def test_api_delete_userstory(client): def test_api_delete_userstory(client):
us = f.UserStoryFactory.create() us = f.UserStoryFactory.create()
f.MembershipFactory.create(project=us.project, user=us.owner, is_owner=True) f.MembershipFactory.create(project=us.project, user=us.owner, is_owner=True)