Splitting big tasks into smaller one!
So I've been thinking, why I'm so not productive lately - and I've found reason - I've been scared of big tasks that consumes a lot of time!
I've decided to spend at least one Pomodoro timer (25 minutes) for splitting issues on Biking-Endorphines project.
At least ones that are estimated on more then 4 h.
Endorphine-Badges-Acquired #23
While reading this issue I've found it's not properly specified and should be splitted into smaller issues/features to make it more "pomodoro-a-like".
So I've added additional 2 tasks that helped me a lot to make progress with this issue.
Subtasks of #23 : #44 and #45
Endpoint for gathering all acquired badges needed 2 models with following them tables : - Badges - UserBadges
And then I could work on creating endpoint with serializer.
So I've created corresponding [REST-API] Badges Model needed #44 and [REST-API] Badge-To-User model #45 and described them as specific as I could.
Pomodoro Technique Timer from Toggl :)
I've also recently started testing new platform called Toggl - for tracking time.
It has such a fancy-pancy chrome-addon that helps to track of time for specific github-issue and has build-in pomodoro timer that after 25 minutes can trigger notification from browser.
Using it helped me with "high-density" working on issues above.
Bugs /Features I've found while working
I've found few bugs/features that I'll be working on soon after this Python-Milestone will end.
Bugs:
- [REST-API] Generic Model Test Case needs fields types check #48
- [REST-API] Point model fields lat-lon unique #51
Features:
- [REST-API] Add processing method for adding new route endpoint #47
- [REST-API] Need to create Test-cases for unicode checking of Models #50
- [REST-API] Endpoint for adding new routes should take json content in body. #46
The #47 and #46 were put into Python-Milestone because they are closely related with #26
Final version
Test code:
- at api/tests/test_unit.py:
class TestUserBadgeSerializer(unittest.TestCase):
"UserBadge Serializer test"
def test_user_badge_serialize(self):
"Tests if user_badge object serialize with RouteSerializer"
user = User()
user.id = 21
user.name = "Anselmos"
user.surname = "Somlesna"
user.weight = 80
user.height = 175
badge = Badge()
badge.id = 1
badge.name = 'FasterThenUniverse'
badge.description = 'you\'re average lap was faster then previous one'
route = Route()
route.id = 2
route.route_name = "NameOfThisFancyRoute"
route.avg_route = 19.9
input_user_badge = UserBadge()
input_user_badge.id_user = user
input_user_badge.id_badge = badge
input_user_badge.id_route = route
input_user_badge.active = True
input_user_badge.badge_acquiring_date = "2017-03-03T12:00:00+00:00"
input_user_badge.activation_modification_date = "2017-03-03T12:00:00+00:00"
input_serialized = UserBadgeSerializer(input_user_badge)
self.assertEqual(
(input_serialized.data),
{
'id': None,
'id_badge': 1,
'id_user': 21,
'id_route': 2,
'active': True,
'badge_acquiring_date': '2017-03-03T12:00:00+00:00',
'activation_modification_date': '2017-03-03T12:00:00+00:00',
}
)
- at
api/tests/test_integration.py::APIGeneralTestCase
# pylint: disable=no-self-use
def create_badge_in_db(self):
" Creates new badge object in database "
return Badge.objects.create(
name='FasterThenUniverse',
description='you\'re average lap was faster then previous one'
)
# pylint: disable=no-self-use
def create_route_in_db(self):
" Creates new route object in database "
return Route.objects.create(route_name="NameOfThisFancyRoute", avg_route=19.9)
# pylint: disable=no-self-use
# pylint: disable=too-many-arguments
def create_user_badge_in_db(self, user, badge, route, active, badge_date, activation_date):
" Creates new UserBadge object in database "
return UserBadge.objects.create(
id_user=user,
id_badge=badge,
id_route=route,
active=active,
badge_acquiring_date=badge_date,
activation_modification_date=activation_date,
)
- at
api/tests/test_integration.py
class TestUserBadgeList(APIGeneralTestCase):
"User Update tests"
def setUp(self):
super(self.__class__, self).setUp()
self.view = UserBadgeList.as_view()
def test_update_user(self):
" Tests if making api request updates user with new name"
badge = self.create_badge_in_db()
route = self.create_route_in_db()
user = self.create_user_in_db()
date_badge_acquired = "2017-02-02T22:00:00"
date_badge_activation = "2017-02-02T22:00:00"
user_badge = self.create_user_badge_in_db(
user,
badge,
route,
True,
date_badge_acquired + "+00:00",
date_badge_activation + "+00:00"
)
self.path = "/api/badge/{}/".format(user_badge.id)
response = self.get_response_user_api(
pk_id=user.id
)
self.assertEquals(response.status_code, 200)
self.assert_user_badge(
response.data[0],
user.id,
badge.id,
route.id,
user_badge.active,
unicode(date_badge_acquired + "Z"),
unicode(date_badge_activation + "Z")
)
# pylint: disable=too-many-arguments
def assert_user_badge(
self, user_badge_object, user_id, badge_id, route_id,
active, badge_acquiring_date, activation_modification_date):
""" Asserts user badge object with parameters """
self.assertEquals(user_badge_object['id_user'], user_id)
self.assertEquals(user_badge_object['id_badge'], badge_id)
self.assertEquals(user_badge_object['id_route'], route_id)
self.assertEquals(user_badge_object['active'], active)
self.assertEquals(
user_badge_object['badge_acquiring_date'],
badge_acquiring_date
)
self.assertEquals(
user_badge_object['activation_modification_date'],
activation_modification_date
)
Source Code:
- at web/models.py:
class Badge(models.Model):
"Badge Model"
name = models.CharField(
max_length=50,
help_text="describes in short name of the badge"
)
description = models.CharField(
max_length=256,
default="",
help_text="More thorough information about badge acquiring (i.e. criteria)"
)
def __unicode__(self):
"Returns Badge unicode as name: description "
return "{}: {}".format(self.name, self.description)
class UserBadge(models.Model):
"Users acquired Badges!"
id_user = models.ForeignKey(User, on_delete=models.CASCADE)
id_badge = models.ForeignKey(Badge, on_delete=models.CASCADE)
id_route = models.ForeignKey(
Route,
on_delete=models.CASCADE,
help_text="id of route on which badge has been acquired"
)
active = models.BooleanField(default=True)
badge_acquiring_date = models.DateTimeField()
activation_modification_date = models.DateTimeField()
def __unicode__(self):
"Returns Badge unicode as name: description "
return "User : {}, Badge acquired-id: {}: "\
"Route-id: {}, active?: {}, badge_acquired_date: {}, "\
"activation_modification_date: {}".format(
self.id_user,
self.id_badge,
self.id_route,
self.active,
self.badge_acquiring_date,
self.activation_modification_date
)
- at api/serializers.py:
class UserBadgeSerializer(serializers.ModelSerializer):
"""
User serializer
"""
class Meta:
model = UserBadge
fields = (
'id',
'id_badge',
'id_user',
'id_route',
'active',
'badge_acquiring_date',
'activation_modification_date'
)
def create(self, validated_data):
"""
Create and return a new `UserBadge` instance, given the validated data.
"""
return UserBadge.objects.create(**validated_data)
- at api/views.py:
class UserBadgeList(generics.ListCreateAPIView):
"""
get:
Return a list of all existing user badges.
"""
queryset = UserBadge.objects.all()
serializer_class = UserBadgeSerializer
Code commits done for this post:
In branch feature/44-Badge-model-needed:
In branch feature/45-Badge-to-User-model:
In branch feature/23-Endorphine-badges-acquired:
- Fixes #23. Fixes pylint issues
- Adds passing integration test for UserBadge API
- Adds failing UserBadge integration test.
- Adds UserBadge Serializer with UnitTests.
- Fixes #45. Adds UserBadge Model with tests. (#53)
- Adds Badge Model to web-models. Fixes #44. (#49)
Release:
What's next
Hunting never ends!! .
I'm still on my python-hunting for collecting as much of Python Milestone Issues as I can :
Due by May 31, 2017 66% complete (9 Open/ 18 Closed)
Thanks! See you soon!
Comments
comments powered by Disqus