Fix #5408 - ignore non-int offset in api feed
authorLoic Dachary <loic@dachary.org>
Mon, 25 Jan 2016 10:26:33 +0000 (17:26 +0700)
committerChristopher Allan Webber <cwebber@dustycloud.org>
Mon, 25 Jan 2016 20:09:19 +0000 (12:09 -0800)
In the same fashion limit=BAD fallsback to the default value,
fallback to zero when offset=WORSE.

Also add test coverage verifying limit/offset do the right thing.

Signed-off-by: Loic Dachary <loic@dachary.org>
mediagoblin/api/views.py
mediagoblin/tests/test_api.py

index dcd04cd6151503578cfc31ffe1806262ef263b59..74181fdeefacb5a7f08bf77785572f94dc6bda74 100644 (file)
@@ -587,7 +587,12 @@ def feed_endpoint(request, outbox=None):
     outbox = outbox.limit(limit)
 
     # Offset (default: no offset - first <count>  result)
-    outbox = outbox.offset(request.args.get("offset", 0))
+    offset = request.args.get("offset", 0)
+    try:
+        offset = int(offset)
+    except ValueError:
+        offset = 0
+    outbox = outbox.offset(offset)
 
     # Build feed.
     for activity in outbox:
index 10bf08fe83a828f6f0838ff322a86f404c6dd353..33b9320860d45e53d5fa1eb6f9ed63ae1ee2b1b8 100644 (file)
@@ -438,8 +438,8 @@ class TestAPI(object):
 
     def test_read_feed(self, test_app):
         """ Test able to read objects from the feed """
-        response, data = self._upload_image(test_app, GOOD_JPG)
-        response, data = self._post_image_to_feed(test_app, data)
+        response, image_data = self._upload_image(test_app, GOOD_JPG)
+        response, data = self._post_image_to_feed(test_app, image_data)
 
         uri = "/api/user/{0}/feed".format(self.active_user.username)
         with self.mock_oauth():
@@ -462,6 +462,48 @@ class TestAPI(object):
             assert feed["items"][0]["object"]["objectType"] == "image"
             assert feed["items"][0]["object"]["id"] == data["object"]["id"]
 
+        default_limit = 20
+        items_count = default_limit * 2
+        for i in range(items_count):
+            response, image_data = self._upload_image(test_app, GOOD_JPG)
+            self._post_image_to_feed(test_app, image_data)
+        items_count += 1  # because there already is one
+
+        #
+        # default returns default_limit items
+        #
+        with self.mock_oauth():
+            response = test_app.get(uri)
+            feed = json.loads(response.body.decode())
+            assert len(feed["items"]) == default_limit
+
+        #
+        # silentely ignore count and offset that that are
+        # not a number
+        #
+        with self.mock_oauth():
+            response = test_app.get(uri + "?count=BAD&offset=WORSE")
+            feed = json.loads(response.body.decode())
+            assert len(feed["items"]) == default_limit
+
+        #
+        # if offset is less than default_limit items
+        # from the end of the feed, return less than
+        # default_limit
+        #
+        with self.mock_oauth():
+            near_the_end = items_count - default_limit / 2
+            response = test_app.get(uri + "?offset=%d" % near_the_end)
+            feed = json.loads(response.body.decode())
+            assert len(feed["items"]) < default_limit
+
+        #
+        # count=5 returns 5 items
+        #
+        with self.mock_oauth():
+            response = test_app.get(uri + "?count=5")
+            feed = json.loads(response.body.decode())
+            assert len(feed["items"]) == 5
 
     def test_read_another_feed(self, test_app):
         """ Test able to read objects from someone else's feed """