diff --git a/addon/serializers/drf.js b/addon/serializers/drf.js index 055a764..85864ef 100644 --- a/addon/serializers/drf.js +++ b/addon/serializers/drf.js @@ -93,7 +93,6 @@ export default DS.RESTSerializer.extend({ let convertedPayload = {}; if (!Ember.isNone(payload) && - payload.hasOwnProperty('count') && payload.hasOwnProperty('next') && payload.hasOwnProperty('previous') && payload.hasOwnProperty('results')) { diff --git a/docs/pagination.md b/docs/pagination.md index 2a9d51e..46f9795 100644 --- a/docs/pagination.md +++ b/docs/pagination.md @@ -104,6 +104,26 @@ export default DRFSerializer.extend({ }); ``` +## Cursor Pagination + +To use [`CursorPagination`](http://www.django-rest-framework.org/api-guide/pagination/#cursorpagination), override `extractPageNumber` in the serializer to extract the `cursor`. + +```js +// app/serializer/drf.js + +import DRFSerializer from 'ember-django-adapter/serializers/drf'; + +export default DRFSerializer.extend({ + extractPageNumber: function(url) { + var match = /.*?[\?&]cursor=([A-Za-z0-9]+).*?/.exec(url); + if (match) { + return match[1]; + } + return null; + } +}); +``` + If you don't use the `PageNumberPagination` for pagination with DRF 3.1 you can also add the metadata for the pagination scheme you use here. We may add support for the other pagination classes in the future. If this is something you are interested in contributing, diff --git a/tests/acceptance/pagination-test.js b/tests/acceptance/cursor-pagination-test.js similarity index 72% rename from tests/acceptance/pagination-test.js rename to tests/acceptance/cursor-pagination-test.js index ff655cf..44d200d 100644 --- a/tests/acceptance/pagination-test.js +++ b/tests/acceptance/cursor-pagination-test.js @@ -49,7 +49,7 @@ var posts = [ } ]; -module('Acceptance: Pagination', { +module('Acceptance: Cursor Pagination', { beforeEach: function() { application = startApp(); @@ -98,7 +98,6 @@ module('Acceptance: Pagination', { var offset = (page - 1) * pageSize; return [200, {'Content-Type': 'application/json'}, JSON.stringify({ - count: posts.length, next: nextUrl, previous: previousUrl, results: posts.slice(offset, offset + pageSize) @@ -114,9 +113,9 @@ module('Acceptance: Pagination', { }); test('Retrieve list of paginated records', function(assert) { - assert.expect(7); + assert.expect(6); - return store.query('post', {page: 1}).then(function(response) { + return store.query('post', {}).then(function(response) { assert.ok(response); assert.equal(response.get('length'), 4); @@ -127,7 +126,6 @@ test('Retrieve list of paginated records', function(assert) { assert.equal(post.get('body'), 'post body 2'); var metadata = response.get('meta'); - assert.equal(metadata.count, 6); assert.equal(metadata.next, 2); assert.equal(metadata.previous, null); }); @@ -140,46 +138,3 @@ test('queryRecord with paginated results returns a single record', function(asse assert.equal(post.get('body'), 'post body 1'); }); }); - -test("Type metadata doesn't have previous", function(assert) { - assert.expect(4); - - return store.query('post', {page: 1}).then(function(response) { - assert.ok(response); - - var metadata = response.get('meta'); - assert.equal(metadata.count, 6); - assert.equal(metadata.next, 2); - assert.equal(metadata.previous, null); - }); -}); - - -test("Type metadata doesn't have next", function(assert) { - assert.expect(5); - - return store.query('post', {page: 2}).then(function(response) { - assert.ok(response); - assert.equal(response.get('length'), 2); - - var metadata = response.get('meta'); - assert.equal(metadata.count, 6); - assert.equal(metadata.next, null); - assert.equal(metadata.previous, 1); - }); -}); - - -test("Test page_size query param", function(assert) { - assert.expect(5); - - return store.query('post', {page: 2, page_size: 2}).then(function(response) { - assert.ok(response); - assert.equal(response.get('length'), 2); - - var metadata = response.get('meta'); - assert.equal(metadata.count, 6); - assert.equal(metadata.previous, 1); - assert.equal(metadata.next, 3); - }); -}); diff --git a/tests/unit/serializers/drf-test.js b/tests/unit/serializers/drf-test.js index ed8feb4..4327cd6 100644 --- a/tests/unit/serializers/drf-test.js +++ b/tests/unit/serializers/drf-test.js @@ -34,6 +34,34 @@ test('normalizeResponse - results', function(assert) { assert.equal(modifiedPayload.meta['other'], 'stuff'); }); +test('normalizeResponse - results (cursor pagination)', function(assert) { + let serializer = this.subject(); + serializer._super = sinon.spy(); + let primaryModelClass = {modelName: 'person'}; + let payload = { + next: '/api/posts/?page=3', + previous: '/api/posts/?page=1', + other: 'stuff', + results: ['result'] + }; + + serializer.normalizeResponse('store', primaryModelClass, payload, 1, 'requestType'); + assert.equal(serializer._super.callCount, 1); + assert.equal(serializer._super.lastCall.args[0],'store'); + assert.propEqual(serializer._super.lastCall.args[1], primaryModelClass); + assert.equal(serializer._super.lastCall.args[3], 1); + assert.equal(serializer._super.lastCall.args[4], 'requestType'); + + let modifiedPayload = serializer._super.lastCall.args[2]; + assert.equal('result', modifiedPayload[primaryModelClass.modelName][0]); + + assert.ok(modifiedPayload.meta); + assert.equal(modifiedPayload.meta['next'], 3); + assert.equal(modifiedPayload.meta['previous'], 1); + // Unknown metadata has been passed along to the meta object. + assert.equal(modifiedPayload.meta['other'], 'stuff'); +}); + test('normalizeResponse - no results', function(assert) { let serializer = this.subject(); serializer._super = sinon.stub().returns('extracted array');