[Backport] Status and default status can be None
parent
2e54452f08
commit
c44852b6be
|
@ -266,7 +266,7 @@ def userstory_freezer(us) -> dict:
|
|||
snapshot = {
|
||||
"ref": us.ref,
|
||||
"owner": us.owner_id,
|
||||
"status": us.status_id,
|
||||
"status": us.status.id if us.status else None,
|
||||
"is_closed": us.is_closed,
|
||||
"finish_date": str(us.finish_date),
|
||||
"backlog_order": us.backlog_order,
|
||||
|
@ -297,7 +297,7 @@ def issue_freezer(issue) -> dict:
|
|||
snapshot = {
|
||||
"ref": issue.ref,
|
||||
"owner": issue.owner_id,
|
||||
"status": issue.status_id,
|
||||
"status": issue.status.id if issue.status else None,
|
||||
"priority": issue.priority_id,
|
||||
"severity": issue.severity_id,
|
||||
"type": issue.type_id,
|
||||
|
@ -321,7 +321,7 @@ def task_freezer(task) -> dict:
|
|||
snapshot = {
|
||||
"ref": task.ref,
|
||||
"owner": task.owner_id,
|
||||
"status": task.status_id,
|
||||
"status": task.status.id if task.status else None,
|
||||
"milestone": task.milestone_id,
|
||||
"subject": task.subject,
|
||||
"description": task.description,
|
||||
|
|
|
@ -98,4 +98,4 @@ class Issue(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, models.
|
|||
|
||||
@property
|
||||
def is_closed(self):
|
||||
return self.status.is_closed
|
||||
return self.status is not None and self.status.is_closed
|
||||
|
|
|
@ -117,7 +117,7 @@ def issues_to_csv(project, queryset):
|
|||
"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_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,
|
||||
"priority": issue.priority.name,
|
||||
"type": issue.type.name,
|
||||
|
|
|
@ -23,6 +23,8 @@ from django.utils import timezone
|
|||
####################################
|
||||
|
||||
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:
|
||||
instance.finished_date = timezone.now()
|
||||
elif not instance.status.is_closed and instance.finished_date:
|
||||
|
|
|
@ -23,7 +23,7 @@ from . import models
|
|||
|
||||
def calculate_milestone_is_closed(milestone):
|
||||
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()]))
|
||||
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ def get_stats_for_project_issues(project):
|
|||
)
|
||||
for issue in issues:
|
||||
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
|
||||
else:
|
||||
project_issues_stats['opened_issues'] += 1
|
||||
|
|
|
@ -68,7 +68,7 @@ class TaskSerializer(WatchersValidator, VoteResourceSerializerMixin, EditableWat
|
|||
return mdrender(obj.project, obj.description)
|
||||
|
||||
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):
|
||||
|
|
|
@ -129,9 +129,9 @@ def tasks_to_csv(project, queryset):
|
|||
"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_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_closed": task.status.is_closed,
|
||||
"is_closed": task.status is not None and task.status.is_closed,
|
||||
"us_order": task.us_order,
|
||||
"taskboard_order": task.taskboard_order,
|
||||
"attachments": task.attachments.count(),
|
||||
|
|
|
@ -100,6 +100,8 @@ def _try_to_close_milestone_when_delete_task(instance):
|
|||
####################################
|
||||
|
||||
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:
|
||||
instance.finished_date = timezone.now()
|
||||
elif not instance.status.is_closed and instance.finished_date:
|
||||
|
|
|
@ -106,9 +106,9 @@ def calculate_userstory_is_closed(user_story):
|
|||
return False
|
||||
|
||||
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 False
|
||||
|
@ -179,7 +179,7 @@ def userstories_to_csv(project,queryset):
|
|||
"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_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,
|
||||
"backlog_order": us.backlog_order,
|
||||
"sprint_order": us.sprint_order,
|
||||
|
|
|
@ -71,6 +71,27 @@ def test_create_issue_without_status(client):
|
|||
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):
|
||||
project = f.create_project()
|
||||
f.MembershipFactory(project=project, user=project.owner, is_owner=True)
|
||||
|
|
|
@ -53,6 +53,19 @@ def test_create_task_without_status(client):
|
|||
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):
|
||||
project = f.ProjectFactory.create()
|
||||
task = f.create_task(project=project, status__project=project, milestone=None, user_story=None)
|
||||
|
|
|
@ -79,6 +79,19 @@ def test_create_userstory_without_status(client):
|
|||
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):
|
||||
us = f.UserStoryFactory.create()
|
||||
f.MembershipFactory.create(project=us.project, user=us.owner, is_owner=True)
|
||||
|
|
Loading…
Reference in New Issue