Long Time No See

It's been a long time since I've been looking into this project from code-perspective.

I needed few deeper moments with it to find myself again in it after those 2 months (woooot??) - yeah...

What task should I get ?

That's the first thing I've asked myself.

I've grabed github issues to investigate on which task would not need so much time.

Initially I've started looking at issues estimated for 2h.

I have found issue on which I was working on - the #55 - subtask of #46 which in fact is also a subtask of #26.

It was not foreseen by me at first glance - initially I've started working on #55 - then I've found out about #46 from commits in repository - Then I've found what problem I've been struggling with last time.

The infamous File-Upload with Route-information.

This time I've decided to move with different approach - step-by-step - not all-in-one :)

To the #56 !

After re-thinking this problem I've found out that without Point serializer I will not be able to create Route-serializer.

So I've changed my mind and instead of working on #46 I went with making Point-Serializer instead of resolving issues with File-Uploading/Json Uploading( json uploading in fact is working properly - nothing to work on in that area)

Fixing time!

Code I've found did not work properly - it failed at 2 levels - both pylint's perspective and pytests were broken.

I decided to first fix the pytests perspective - cause fixing pylint's perspective would give a false-positive affect that It's done - which in fact could not be after making changes for pytests working properly.

Final result

Finally I've completed only part of Point-Serializer - for making only single point creation instead of bulk. I will find out what was wrong with my code next time.

Source Code:

1. In api/serializers.py

class PointListSerializer(serializers.ListSerializer):
    """
    Point List serializer
    """

    def create(self, validated_data):
        """
        Create and return list of a new `Point` instances, given the validated data.
        """
        points = [Point(**item) for item in validated_data]
        return Point.objects.bulk_create(points)

    def update(self, instance, validated_data):
        # Maps for id->instance and id->data item.
        point_mapping = {point.id: point for point in instance}
        data_mapping = {item['id']: item for item in validated_data}

        # Perform creations and updates.
        ret = []
        for point_id, data in data_mapping.items():
            point = point_mapping.get(point_id, None)
            if point is None:
                ret.append(self.child.create(data))
            else:
                ret.append(self.child.update(point, data))

        # Perform deletions.
        for point_id, point in point_mapping.items():
            if point_id not in data_mapping:
                point.delete()

        return ret



class PointSerializer(serializers.ModelSerializer):
    """
    Point serializer
    """
    class Meta:
        model = Point
        fields = ('id', 'lat', 'lon', 'elevation', 'time')
        list_serializer_class = PointListSerializer

    def create(self, validated_data):
        """
        Create and return a new `Point` instance, given the validated data.
        """
        return Point.objects.create(**validated_data)

2. In web/models added time field in Point.

Tests:

1. In api/tests/test_integration.py

class TestFileUploadView(APIGeneralTestCase):
    "File Upload tests"
    def setUp(self):
        super(self.__class__, self).setUp()
        self.api = APIRequestFactory().post
        self.view = FileUploadView.as_view()

    @unittest.skip("test not ready")
    def test_json_file(self):
        """
        This test has been setup as skipped temporarily - because it does not make what it should
        Tests if making api request for uploading json file succeed
        """

        import os
        dir_path = os.path.dirname(os.path.realpath(__file__))
        file_ = open(dir_path + '/samples/routesample.json', 'rb')

        api_data = {'filename':  file_}

        self.client.credentials(HTTP_AUTHORIZATION='Token {}'.format(self.token))
        request = self.api(
            "/api/file/",
            api_data,
            format='json',
            HTTP_AUTHORIZATION='Token {}'.format(self.token),
        )
        response = self.view(request, format='json')
        assert response.status_code == 202


class TestPointView(APIGeneralTestCase):
    """ Tests for Point View"""

    def setUp(self):
        super(self.__class__, self).setUp()
        self.api = APIRequestFactory().post
        self.view = PointView.as_view()
        self.path = "/api/point/"

    def test_uploading_one_point(self):
        " Tests if making api request updates user with new name"

        data = json.dumps(
            {
                "lat": "11.22",
                "lon": "11.33",
                "time": "2001-01-22T07:05:05Z",
                "ele": "11.1",
            }
        )
        response = self.get_response_user_api(
            data
        )
        self.assertEquals(response.status_code, 201)
        all_points = Point.objects.all()
        self.assertEquals(len(all_points), 1)


class TestPointListView(APIGeneralTestCase):
    """ Tests for List of Points View"""

    def setUp(self):
        super(self.__class__, self).setUp()
        self.api = APIRequestFactory().post
        self.view = PointList.as_view()
        self.path = "/api/points/"


    @unittest.skip("test not ready")
    def test_uploading_multiple_points(self):
        " Tests if making api request updates user with new name"
        data = json.dumps([
            {
                "lat": "11.22",
                "lon": "11.33",
                "time": "2001-01-22T07:05:05Z",
                "ele": "11.1",
            },
            {
                "lat": "22.22",
                "lon": "22.33",
                "time": "2001-01-22T07:05:05Z",
                "ele": "22.1",
            }
        ])
        response = self.get_response_user_api(
            data
        )
        self.assertEquals(response.status_code, 200)
        all_points = Point.objects.all()
        self.assertEquals(len(all_points), 2)

2. In api/tests/test_unit.py:

class TestPointSerializer(unittest.TestCase):
    "Point Serializer test"

    def test_point_serialize(self):
        "Tests if Point object serialize with PointSerializer"
        input_point = Point()
        input_point.lat = 33.2
        input_point.lon = 34.2
        input_point.elevation = 11.2
        input_point.time = "2017-03-03T12:00:00+00:00"
        input_serialized = PointSerializer(input_point)
        self.assertEqual(
            (input_serialized.data),
            {
                'id': None,
                'lat': 33.2,
                'lon': 34.2,
                'elevation': 11.2,
                'time': "2017-03-03T12:00:00+00:00"
            }
        )

    def test_point_list_serialize(self):
        "Tests if Point object serialize with PointSerializer"
        input_point = Point()
        input_point.lat = 11.1
        input_point.lon = 11.1
        input_point.elevation = 11.1
        input_point.time = "2011-01-01T11:00:00+00:00"

        input_point2 = Point()
        input_point2.lat = 22.2
        input_point2.lon = 22.2
        input_point2.elevation = 22.2
        input_point2.time = "2012-02-02T12:00:00+00:00"
        input_serialized = PointSerializer([input_point, input_point2], many=True)
        self.assertEqual(
            (input_serialized.data),
            [
                OrderedDict(
                    [
                        ('id', None),
                        ('lat', 11.1),
                        ('lon', 11.1),
                        ('elevation', 11.1),
                        ('time', '2011-01-01T11:00:00+00:00')
                    ]
                ),
                OrderedDict(
                    [
                        ('id', None),
                        ('lat', 22.2),
                        ('lon', 22.2),
                        ('elevation', 22.2),
                        ('time', '2012-02-02T12:00:00+00:00')
                    ]
                )
            ]
        )

Code commits done for this post:

Release:

16-07-2017-point-serializer

What else I've found out when looking into code and environment I'm currently working on?

1. Lack of debug mode when using tests which in fact may help to figure out problems with code.

2. Pylint's report contains too much information when developing and fixing - it leads to problems but it's too much of data (simple file line and error of that line would be enough)

3. Development environment for writing drafts of articles needs a bit of my attention to make it a bit simpler to use.

4. Figure out that I need a plugin in pelican that will automatically convert issues numbers into http-links to project in some fancy-way that I would only need to put the [#46] and it would be enough for pelican plugin to read it and convert to [#46](https://github.com/anselmos/Biking-Endorphines/issues/46)

5. Lack of a simplified check-list that I'll use each time writing blog post and developing b-endorphines.

To Be Continued - See you next time!

Till next time



Comments

comments powered by Disqus