Skip to content

Commit

Permalink
Merge pull request #854 from gabisurita/master
Browse files Browse the repository at this point in the history
Fix filtering with numeric id (fixes #851)
  • Loading branch information
leplatrem committed Oct 10, 2016
2 parents b2a3793 + 7948e09 commit 5d65d61
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Expand Up @@ -20,6 +20,8 @@ This document describes changes between each past release.
- Fix group association when members contains ``system.Authenticated`` (fixes #776)
- Raise an error when members contains ``system.Everyone`` or a group ID (#850)
- Fix StatsD view counter with 404 responses (#853)
- Fixes filtering on ids with numeric values. (fixes #851)


4.3.0 (2016-10-04)
------------------
Expand Down
4 changes: 4 additions & 0 deletions kinto/core/storage/memory.py
Expand Up @@ -319,6 +319,10 @@ def apply_filters(records, filters):
matches = True
for f in filters:
right = f.value
if f.field == DEFAULT_ID_FIELD:
if isinstance(right, int):
right = str(right)

left = record
subfields = f.field.split('.')
for subfield in subfields:
Expand Down
2 changes: 2 additions & 0 deletions kinto/core/storage/postgresql/__init__.py
Expand Up @@ -641,6 +641,8 @@ def _format_conditions(self, filters, id_field, modified_field,

if filtr.field == id_field:
sql_field = 'id'
if isinstance(value, int):
value = str(value)
elif filtr.field == modified_field:
sql_field = 'as_epoch(last_modified)'
else:
Expand Down
14 changes: 14 additions & 0 deletions kinto/core/storage/testing.py
Expand Up @@ -358,6 +358,20 @@ def test_get_all_can_filter_with_numeric_values(self):
self.assertEqual(records[1]['code'], 6)
self.assertEqual(len(records), 2)

def test_get_all_can_filter_with_numeric_id(self):
for l in [0, 42]:
self.create_record({'id': str(l)})

filters = [Filter('id', 0, utils.COMPARISON.EQ)]
records, _ = self.storage.get_all(filters=filters,
**self.storage_kw)
self.assertEqual(len(records), 1)

filters = [Filter('id', 42, utils.COMPARISON.EQ)]
records, _ = self.storage.get_all(filters=filters,
**self.storage_kw)
self.assertEqual(len(records), 1)

def test_get_all_can_filter_with_numeric_strings(self):
for l in ["0566199093", "0781566199"]:
self.create_record({'phone': l})
Expand Down
12 changes: 12 additions & 0 deletions kinto/plugins/history/views.py
Expand Up @@ -2,6 +2,7 @@

from kinto.core import resource
from kinto.core.utils import instance_uri
from kinto.core.storage import Filter


class HistorySchema(resource.ResourceSchema):
Expand Down Expand Up @@ -31,3 +32,14 @@ class History(resource.ShareableResource):
def get_parent_id(self, request):
self.bucket_id = request.matchdict['bucket_id']
return instance_uri(request, 'bucket', id=self.bucket_id)

def _extract_filters(self, queryparams=None):
filters = super(History, self)._extract_filters(queryparams)
filters_str_id = []
for filt in filters:
if filt.field in ('record_id', 'collection_id', 'bucket_id'):
if isinstance(filt.value, int):
filt = Filter(filt.field, str(filt.value), filt.operator)
filters_str_id.append(filt)

return filters_str_id
25 changes: 25 additions & 0 deletions tests/plugins/test_history.py
Expand Up @@ -320,12 +320,19 @@ class FilteringTest(HistoryWebTest):

def setUp(self):
self.app.put('/buckets/bid', headers=self.headers)
self.app.put('/buckets/0', headers=self.headers)
self.app.put('/buckets/bid/collections/cid',
headers=self.headers)
self.app.put('/buckets/0/collections/1',
headers=self.headers)
body = {'data': {'foo': 42}}
self.app.put_json('/buckets/bid/collections/cid/records/rid',
body,
headers=self.headers)
body = {'data': {'foo': 0}}
self.app.put_json('/buckets/0/collections/1/records/2',
body,
headers=self.headers)
body = {'data': {'foo': 'bar'}}
self.app.patch_json('/buckets/bid/collections/cid/records/rid',
body,
Expand Down Expand Up @@ -381,6 +388,24 @@ def test_filter_by_collection(self):
headers=self.headers)
assert len(resp.json['data']) == 4

def test_filter_by_numeric_bucket(self):
uri = '/buckets/0/history?bucket_id=0'
resp = self.app.get(uri,
headers=self.headers)
assert len(resp.json['data']) == 1

def test_filter_by_numeric_collection(self):
uri = '/buckets/0/history?collection_id=1'
resp = self.app.get(uri,
headers=self.headers)
assert len(resp.json['data']) == 2

def test_filter_by_numeric_record(self):
uri = '/buckets/0/history?record_id=2'
resp = self.app.get(uri,
headers=self.headers)
assert len(resp.json['data']) == 1

def test_filter_by_target_fields(self):
uri = '/buckets/bid/history?target.data.id=rid'
resp = self.app.get(uri,
Expand Down

0 comments on commit 5d65d61

Please sign in to comment.