Skip to content

Commit

Permalink
Fix a bug on project boarding calculation (#980)
Browse files Browse the repository at this point in the history
* Add project model test

* Fix a bug on project boarding calculation, #149

* Enhance tests
  • Loading branch information
shayaniox authored and mohammadsheikhian committed Jul 3, 2019
1 parent 8e6d92c commit c4154f1
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 41 deletions.
49 changes: 16 additions & 33 deletions dolphin/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
OrderingMixin, FilteringMixin, PaginationMixin
from restfulpy.orm.metadata import MetadataField
from sqlalchemy import Integer, ForeignKey, Enum, select, func, bindparam, \
join, case
join, case, exists
from sqlalchemy.orm import column_property
from sqlalchemy.ext.hybrid import hybrid_property

Expand Down Expand Up @@ -172,40 +172,23 @@ class Project(ModifiedByMixin, OrderingMixin, FilteringMixin, PaginationMixin,
deferred=True
)

boarding_value = column_property(
select([func.max(Issue.boarding_value)])
.where(Issue.project_id == id)
.where(status == 'active')
boarding = column_property(
case([
(
status == 'queued',
None
),
(
exists(
select([Issue.id])
.where(Issue.project_id == id)
.where(Issue.boarding == 'delayed')
),
'delayed'
)], else_='on-time'
)
)

@hybrid_property
def boarding(self):
if self.status == 'on-hold':
return Boarding.frozen[1]

elif self.status == 'queued':
return None

elif self.boarding_value == Boarding.ontime[0]:
return Boarding.ontime[1]

elif self.boarding_value == Boarding.delayed[0]:
return Boarding.delayed[1]

elif self.boarding_value == Boarding.frozen[0]:
return Boarding.frozen[1]

return None

@boarding.expression
def boarding(cls):
return case([
(cls.status == 'on-hold', Boarding.frozen[1]),
(cls.boarding_value == Boarding.ontime[0], Boarding.ontime[1]),
(cls.boarding_value == Boarding.delayed[0], Boarding.delayed[1]),
(cls.boarding_value == Boarding.frozen[0], Boarding.frozen[1]),
])

@classmethod
def iter_metadata_fields(cls):
yield from super().iter_metadata_fields()
Expand Down
2 changes: 1 addition & 1 deletion dolphin/tests/test_project_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def test_create(self):
assert response.json['title'] == 'My awesome project'
assert response.json['description'] == 'A decription for my project'
assert response.json['status'] == 'active'
assert response.json['boarding'] == None
assert response.json['boarding'] == 'on-time'
assert response.json['dueDate'] == None
assert response.json['managerId'] == self.member.id
assert response.json['secondaryManagerId'] is None
Expand Down
13 changes: 6 additions & 7 deletions dolphin/tests/test_project_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,8 @@ def test_list(self):
assert status == 200
assert len(response.json) == 4
assert response.json[0]['title'] == self.project1.title
assert response.json[1]['title'] == self.project3.title
assert response.json[2]['title'] == self.project2.title
assert response.json[1]['title'] == self.project2.title
assert response.json[2]['title'] == self.project3.title
assert response.json[3]['title'] == self.project4.title

when(
Expand All @@ -354,8 +354,8 @@ def test_list(self):
assert status == 200
assert len(response.json) == 4
assert response.json[0]['title'] == self.project3.title
assert response.json[1]['title'] == self.project2.title
assert response.json[2]['title'] == self.project1.title
assert response.json[1]['title'] == self.project1.title
assert response.json[2]['title'] == self.project2.title
assert response.json[3]['title'] == self.project4.title

with self.given(
Expand Down Expand Up @@ -384,7 +384,7 @@ def test_list(self):
query=dict(sort='id', status='on-hold')
)
assert response.json[0]['status'] == 'on-hold'
assert response.json[0]['boarding'] == 'frozen'
assert response.json[0]['boarding'] == 'on-time'

when(
'List projects excepts one of statuses',
Expand All @@ -397,8 +397,7 @@ def test_list(self):
query=dict(boarding='on-time')
)
assert status == 200
assert len(response.json) == 1
assert response.json[0]['title'] == self.project2.title
assert len(response.json) == 3

when(
'Filter project by boarding using IN clause',
Expand Down
126 changes: 126 additions & 0 deletions dolphin/tests/test_project_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
from datetime import datetime

from auditor.context import Context as AuditLogContext
from nanohttp import context
from nanohttp.contexts import Context
from restfulpy.testing import db
from sqlalchemy.orm import aliased

from dolphin.models import Item, Project, Member, Workflow, Group, Release, \
Skill, Phase, Issue, IssuePhase, Dailyreport


def test_boarding(db):
session = db()
session.expire_on_commit = True

with AuditLogContext(dict()):
member = Member(
title='First Member',
email='[email protected]',
access_token='access token 1',
phone=123456789,
reference_id=1
)
session.add(member)
session.commit()

workflow = Workflow(title='Default')
skill = Skill(title='First Skill')
group = Group(title='default')

release = Release(
title='My first release',
description='A decription for my first release',
cutoff='2030-2-20',
launch_date='2030-2-20',
manager=member,
room_id=0,
group=group,
)

project = Project(
release=release,
workflow=workflow,
group=group,
manager=member,
title='My first project',
description='A decription for my project',
room_id=1,
status='active',
)

with Context(dict()):
context.identity = member

issue1 = Issue(
project=project,
title='First issue',
description='This is description of first issue',
days=1,
room_id=2,
)
session.add(issue1)

issue2 = Issue(
project=project,
title='Second issue',
description='This is description of second issue',
kind='feature',
days=2,
room_id=3,
)
session.add(issue2)

phase1 = Phase(
workflow=workflow,
title='Backlog',
order=1,
skill=skill,
)
session.add(phase1)

phase2 = Phase(
workflow=workflow,
title='Test',
order=2,
skill=skill,
)
session.add(phase1)

phase3 = Phase(
workflow=workflow,
title='Development',
order=3,
skill=skill,
)
session.add(phase1)
session.flush()

issue_phase1 = IssuePhase(
issue_id=issue1.id,
phase_id=phase1.id,
)
session.add(issue_phase1)
session.flush()

item1 = Item(
issue_phase_id=issue_phase1.id,
member_id=member.id,
start_date=datetime.strptime('2020-2-2', '%Y-%m-%d'),
end_date=datetime.strptime('2020-2-3', '%Y-%m-%d'),
estimated_hours=4,
)
session.add(item1)
session.commit()

assert project.boarding == 'on-time'

item1.end_date = datetime.strptime('2019-2-3', '%Y-%m-%d'),
session.commit()
assert project.boarding == 'delayed'

project.status = 'queued'
session.commit()
assert project.boarding == None

0 comments on commit c4154f1

Please sign in to comment.