Add create default duedates view to task and issues
parent
5ef687dcf8
commit
3a16a3294c
|
@ -601,7 +601,8 @@ class UserStoryDueDateViewSet(BlockedByProjectMixin, ModelCrudViewSet):
|
||||||
|
|
||||||
def pre_delete(self, obj):
|
def pre_delete(self, obj):
|
||||||
if obj.by_default:
|
if obj.by_default:
|
||||||
raise exc.BadRequest(_("You can't delete by default due date"))
|
raise exc.BadRequest(
|
||||||
|
_("You can't delete user story by default due date"))
|
||||||
|
|
||||||
@list_route(methods=["POST"])
|
@list_route(methods=["POST"])
|
||||||
def create_default(self, request, **kwargs):
|
def create_default(self, request, **kwargs):
|
||||||
|
@ -675,6 +676,42 @@ class TaskDueDateViewSet(BlockedByProjectMixin, ModelCrudViewSet):
|
||||||
with advisory_lock("task-due-date-creation-{}".format(project_id)):
|
with advisory_lock("task-due-date-creation-{}".format(project_id)):
|
||||||
return super().create(request, *args, **kwargs)
|
return super().create(request, *args, **kwargs)
|
||||||
|
|
||||||
|
@list_route(methods=["POST"])
|
||||||
|
def create_default(self, request, **kwargs):
|
||||||
|
context = {
|
||||||
|
"request": request
|
||||||
|
}
|
||||||
|
validator = validators.DueDatesCreationValidator(data=request.DATA,
|
||||||
|
context=context)
|
||||||
|
if not validator.is_valid():
|
||||||
|
return response.BadRequest(validator.errors)
|
||||||
|
|
||||||
|
project_id = request.DATA.get('project_id')
|
||||||
|
project = models.Project.objects.get(id=project_id)
|
||||||
|
|
||||||
|
if project.task_duedates.all():
|
||||||
|
raise exc.BadRequest(_("Project already have task due dates"))
|
||||||
|
|
||||||
|
project_template = models.ProjectTemplate.objects.get(
|
||||||
|
id=project.creation_template.id)
|
||||||
|
|
||||||
|
for task_duedate in project_template.task_duedates:
|
||||||
|
models.TaskDueDate.objects.create(
|
||||||
|
name=task_duedate["name"],
|
||||||
|
slug=task_duedate["slug"],
|
||||||
|
by_default=task_duedate["by_default"],
|
||||||
|
color=task_duedate["color"],
|
||||||
|
days_to_due=task_duedate["days_to_due"],
|
||||||
|
order=task_duedate["order"],
|
||||||
|
project=project
|
||||||
|
)
|
||||||
|
project.save()
|
||||||
|
|
||||||
|
serializer = self.get_serializer(project.task_duedates.all(),
|
||||||
|
many=True)
|
||||||
|
|
||||||
|
return response.Ok(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
class SeverityViewSet(MoveOnDestroyMixin, BlockedByProjectMixin,
|
class SeverityViewSet(MoveOnDestroyMixin, BlockedByProjectMixin,
|
||||||
ModelCrudViewSet, BulkUpdateOrderMixin):
|
ModelCrudViewSet, BulkUpdateOrderMixin):
|
||||||
|
@ -775,6 +812,42 @@ class IssueDueDateViewSet(BlockedByProjectMixin, ModelCrudViewSet):
|
||||||
with advisory_lock("issue-due-date-creation-{}".format(project_id)):
|
with advisory_lock("issue-due-date-creation-{}".format(project_id)):
|
||||||
return super().create(request, *args, **kwargs)
|
return super().create(request, *args, **kwargs)
|
||||||
|
|
||||||
|
@list_route(methods=["POST"])
|
||||||
|
def create_default(self, request, **kwargs):
|
||||||
|
context = {
|
||||||
|
"request": request
|
||||||
|
}
|
||||||
|
validator = validators.DueDatesCreationValidator(data=request.DATA,
|
||||||
|
context=context)
|
||||||
|
if not validator.is_valid():
|
||||||
|
return response.BadRequest(validator.errors)
|
||||||
|
|
||||||
|
project_id = request.DATA.get('project_id')
|
||||||
|
project = models.Project.objects.get(id=project_id)
|
||||||
|
|
||||||
|
if project.issue_duedates.all():
|
||||||
|
raise exc.BadRequest(_("Project already have issue due dates"))
|
||||||
|
|
||||||
|
project_template = models.ProjectTemplate.objects.get(
|
||||||
|
id=project.creation_template.id)
|
||||||
|
|
||||||
|
for issue_duedate in project_template.issue_duedates:
|
||||||
|
models.IssueDueDate.objects.create(
|
||||||
|
name=issue_duedate["name"],
|
||||||
|
slug=issue_duedate["slug"],
|
||||||
|
by_default=issue_duedate["by_default"],
|
||||||
|
color=issue_duedate["color"],
|
||||||
|
days_to_due=issue_duedate["days_to_due"],
|
||||||
|
order=issue_duedate["order"],
|
||||||
|
project=project
|
||||||
|
)
|
||||||
|
project.save()
|
||||||
|
|
||||||
|
serializer = self.get_serializer(project.issue_duedates.all(),
|
||||||
|
many=True)
|
||||||
|
|
||||||
|
return response.Ok(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
######################################################
|
######################################################
|
||||||
## Project Template
|
## Project Template
|
||||||
|
|
|
@ -388,6 +388,15 @@ class UserStoryStatusFactory(Factory):
|
||||||
project = factory.SubFactory("tests.factories.ProjectFactory")
|
project = factory.SubFactory("tests.factories.ProjectFactory")
|
||||||
|
|
||||||
|
|
||||||
|
class UserStoryDueDateFactory(Factory):
|
||||||
|
class Meta:
|
||||||
|
model = "projects.UserStoryDueDate"
|
||||||
|
strategy = factory.CREATE_STRATEGY
|
||||||
|
|
||||||
|
name = factory.Sequence(lambda n: "User Story due date {}".format(n))
|
||||||
|
project = factory.SubFactory("tests.factories.ProjectFactory")
|
||||||
|
|
||||||
|
|
||||||
class TaskStatusFactory(Factory):
|
class TaskStatusFactory(Factory):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = "projects.TaskStatus"
|
model = "projects.TaskStatus"
|
||||||
|
|
|
@ -2289,3 +2289,153 @@ def test_duplicate_public_project_without_enough_memberships_slots(client):
|
||||||
assert "current limit of memberships" in response.data["_error_message"]
|
assert "current limit of memberships" in response.data["_error_message"]
|
||||||
assert response["Taiga-Info-Project-Memberships"] == "2"
|
assert response["Taiga-Info-Project-Memberships"] == "2"
|
||||||
assert response["Taiga-Info-Project-Is-Private"] == "False"
|
assert response["Taiga-Info-Project-Is-Private"] == "False"
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_us_default_due_dates(client):
|
||||||
|
project = f.create_project()
|
||||||
|
|
||||||
|
us_duedates = [{
|
||||||
|
"name": 'Default',
|
||||||
|
"slug": 'default',
|
||||||
|
"by_default": True,
|
||||||
|
'color': '#0000',
|
||||||
|
'days_to_due': None,
|
||||||
|
'order': 0,
|
||||||
|
}]
|
||||||
|
creation_template = project.creation_template
|
||||||
|
creation_template.us_duedates = us_duedates
|
||||||
|
creation_template.save()
|
||||||
|
|
||||||
|
f.MembershipFactory(user=project.owner, project=project, is_admin=True)
|
||||||
|
url = reverse('userstory-due-dates-create-default')
|
||||||
|
data = {"project_id": project.pk}
|
||||||
|
client.login(project.owner)
|
||||||
|
|
||||||
|
response = client.json.post(url, json.dumps(data))
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert project.us_duedates.count() == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_prevent_create_us_default_due_dates_when_already_exists(client):
|
||||||
|
us_duedates = [{
|
||||||
|
"name": 'Default',
|
||||||
|
"slug": 'default',
|
||||||
|
"by_default": True,
|
||||||
|
'color': '#0000',
|
||||||
|
'days_to_due': None,
|
||||||
|
'order': 0,
|
||||||
|
}]
|
||||||
|
f.ProjectTemplateFactory.create(
|
||||||
|
slug=settings.DEFAULT_PROJECT_TEMPLATE, us_duedates=us_duedates)
|
||||||
|
project = f.create_project()
|
||||||
|
|
||||||
|
f.MembershipFactory(user=project.owner, project=project, is_admin=True)
|
||||||
|
url = reverse('userstory-due-dates-create-default')
|
||||||
|
data = {"project_id": project.pk}
|
||||||
|
client.login(project.owner)
|
||||||
|
|
||||||
|
response = client.json.post(url, json.dumps(data))
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert project.us_duedates.count() == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_issue_default_due_dates(client):
|
||||||
|
project = f.create_project()
|
||||||
|
|
||||||
|
issue_duedates = [{
|
||||||
|
"name": 'Default',
|
||||||
|
"slug": 'default',
|
||||||
|
"by_default": True,
|
||||||
|
'color': '#0000',
|
||||||
|
'days_to_due': None,
|
||||||
|
'order': 0,
|
||||||
|
}]
|
||||||
|
creation_template = project.creation_template
|
||||||
|
creation_template.issue_duedates = issue_duedates
|
||||||
|
creation_template.save()
|
||||||
|
|
||||||
|
f.MembershipFactory(user=project.owner, project=project, is_admin=True)
|
||||||
|
url = reverse('issue-due-dates-create-default')
|
||||||
|
data = {"project_id": project.pk}
|
||||||
|
client.login(project.owner)
|
||||||
|
|
||||||
|
response = client.json.post(url, json.dumps(data))
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert project.issue_duedates.count() == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_prevent_create_issue_default_due_dates_when_already_exists(client):
|
||||||
|
issue_duedates = [{
|
||||||
|
"name": 'Default',
|
||||||
|
"slug": 'default',
|
||||||
|
"by_default": True,
|
||||||
|
'color': '#0000',
|
||||||
|
'days_to_due': None,
|
||||||
|
'order': 0,
|
||||||
|
}]
|
||||||
|
f.ProjectTemplateFactory.create(
|
||||||
|
slug=settings.DEFAULT_PROJECT_TEMPLATE, issue_duedates=issue_duedates)
|
||||||
|
project = f.create_project()
|
||||||
|
|
||||||
|
f.MembershipFactory(user=project.owner, project=project, is_admin=True)
|
||||||
|
url = reverse('issue-due-dates-create-default')
|
||||||
|
data = {"project_id": project.pk}
|
||||||
|
client.login(project.owner)
|
||||||
|
|
||||||
|
response = client.json.post(url, json.dumps(data))
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert project.issue_duedates.count() == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_task_default_due_dates(client):
|
||||||
|
project = f.create_project()
|
||||||
|
|
||||||
|
task_duedates = [{
|
||||||
|
"name": 'Default',
|
||||||
|
"slug": 'default',
|
||||||
|
"by_default": True,
|
||||||
|
'color': '#0000',
|
||||||
|
'days_to_due': None,
|
||||||
|
'order': 0,
|
||||||
|
}]
|
||||||
|
creation_template = project.creation_template
|
||||||
|
creation_template.task_duedates = task_duedates
|
||||||
|
creation_template.save()
|
||||||
|
|
||||||
|
f.MembershipFactory(user=project.owner, project=project, is_admin=True)
|
||||||
|
url = reverse('task-due-dates-create-default')
|
||||||
|
data = {"project_id": project.pk}
|
||||||
|
client.login(project.owner)
|
||||||
|
|
||||||
|
response = client.json.post(url, json.dumps(data))
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert project.task_duedates.count() == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_prevent_create_task_default_due_dates_when_already_exists(client):
|
||||||
|
task_duedates = [{
|
||||||
|
"name": 'Default',
|
||||||
|
"slug": 'default',
|
||||||
|
"by_default": True,
|
||||||
|
'color': '#0000',
|
||||||
|
'days_to_due': None,
|
||||||
|
'order': 0,
|
||||||
|
}]
|
||||||
|
f.ProjectTemplateFactory.create(
|
||||||
|
slug=settings.DEFAULT_PROJECT_TEMPLATE, task_duedates=task_duedates)
|
||||||
|
project = f.create_project()
|
||||||
|
|
||||||
|
f.MembershipFactory(user=project.owner, project=project, is_admin=True)
|
||||||
|
url = reverse('task-due-dates-create-default')
|
||||||
|
data = {"project_id": project.pk}
|
||||||
|
client.login(project.owner)
|
||||||
|
|
||||||
|
response = client.json.post(url, json.dumps(data))
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert project.task_duedates.count() == 1
|
||||||
|
|
Loading…
Reference in New Issue