Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-work pagination and add tests. #38

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
cedbc5c
Initial commit
Jun 30, 2014
2e02f11
Add link to toranb repo
Jun 30, 2014
9ab1a0c
Fix directory namespace
Jun 30, 2014
aef6e6e
Version 0.0.1
Jun 30, 2014
3244a73
Use non-minified production build of the adapter
Jun 30, 2014
10fdf3d
Version 0.0.2
Jun 30, 2014
2847983
Add instructions on extending the adapter
Jun 30, 2014
a0303aa
Version 0.1.0
Jul 1, 2014
4afb41d
Upgrade to v1.0.5 of ember-data-django-rest-adapter
Jul 9, 2014
810fcf7
Version 0.2.0
Jul 9, 2014
6a142d4
Add changelog
Jul 9, 2014
1d116b5
Add adapter/serializer blueprints. Fix #1
Jul 13, 2014
6c9abad
Update CHANGELOG.md
Jul 13, 2014
de17814
Fix blueprint index.js
Jul 19, 2014
fc7187f
Add namespace to config options
Jul 21, 2014
33e57bd
Change host/namespace defaults to use Ember's builtin express server
Jul 21, 2014
6eac437
Merge pull request #2 from dustinfarris/ember-server-defaults
Jul 21, 2014
f834854
Update CHANGELOG.md
Jul 21, 2014
9668522
Bump ember-data-django-rest-adapter to v1.0.6
Jul 27, 2014
6aae650
Update CHANGELOG.md
Jul 27, 2014
de84f94
Release v0.3.0
Jul 27, 2014
5c11fa2
New packaging
Jul 27, 2014
bf7bee2
Remove index.js not needed
Jul 27, 2014
3ded062
Update CHANGELOG.md
Jul 27, 2014
9805487
Merge pull request #5 from dustinfarris/new-packaging
Jul 27, 2014
341f50e
Add blueprintsPath to main export
Jul 27, 2014
3c50741
Merge branch 'new-packaging'
Jul 27, 2014
5f82668
Update README.md
Jul 29, 2014
25c3b3b
Fix for "Cannot read property 'pkg' of null" error
holandes22 Sep 27, 2014
5caf599
Merge pull request #8 from holandes22/master
Sep 27, 2014
8eff6e5
Update CHANGELOG.md
Sep 27, 2014
c26360d
Update README.md
Oct 5, 2014
a25c26b
Add ember-cli link to readme
Oct 5, 2014
2a5449f
meaningful example in readme
Oct 5, 2014
6c2c663
Release v0.4.0
Oct 5, 2014
84054d7
add roadmap to readme
Nov 18, 2014
75b7379
Bump version to 0.5.0
Jan 4, 2015
ec1e04e
Update changelog with v0.5.0 notes
Jan 4, 2015
ebfa445
Merge branch 'master' into version-1.0
Jan 4, 2015
bbd9155
Re-work pagination and add tests.
benkonrath Dec 12, 2014
2918dcb
Implement improvements from @dustinfarris' review.
benkonrath Dec 15, 2014
f3b56c0
Use camelCase variable names in pagination integration tests.
benkonrath Dec 15, 2014
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
ember-django-adapter Changelog
==============================

0.5.0
-----

This version is a complete rewrite of the adapter. It represents a cherry-
picking of the original adapter from toranb, implemented using ember-cli's
addon framework. This version is required for recent versions of Ember Data
and Ember CLI, but it is still very much a work-in-progress.

**All CHANGELOG history before this point is inapplicable.**


0.4.0
-----

Expand Down
26 changes: 23 additions & 3 deletions addon/serializers/drf.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ import Ember from 'ember';
*/
export default DS.RESTSerializer.extend({

/**
* Returns the number extracted from the page number query param of
* a `url`. `null` is returned when the page number query param
* isn't present in the url. `null` is also returned when `url` is
* `null`.
*
* @method extractPageNumber
* @private
* @param {String} url
* @return {Number} page number
*/
extractPageNumber: function(url) {
var match = /.*?[\?&]page=(\d+).*?/.exec(url);
if (match) {
return Number(match[1]).valueOf();
}
return null;
},

/**
* `extractMeta` is used to deserialize any meta information in the
* adapter payload. By default Ember Data expects meta information to
Expand All @@ -26,10 +45,11 @@ export default DS.RESTSerializer.extend({
if (payload && payload.results) {
// Sets the metadata for the type.
store.metaForType(type, {
total: payload.count,
next: payload.next,
previous: payload.previous
count: payload.count,
next: this.extractPageNumber(payload.next),
previous: this.extractPageNumber(payload.previous)
});

// Keep ember data from trying to parse the metadata as a records
delete payload.count;
delete payload.next;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ember-django-adapter",
"version": "1.0.0-dev",
"version": "0.5.0",
"description": "Use Django REST Framework with your Ember project",
"directories": {
"doc": "doc",
Expand Down
7 changes: 0 additions & 7 deletions tests/dummy/app/models/paginated-post.js

This file was deleted.

24 changes: 0 additions & 24 deletions tests/integration/crud-success-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,6 @@ module('CRUD Success', {
return [200, {'Content-Type': 'application/json'}, JSON.stringify(posts)];
});

// Retrieve list of paginated records
this.get('/test-api/paginated-posts/', function(request) {
return [200, {'Content-Type': 'application/json'}, JSON.stringify({results: posts})];
});

// Retrieve single record
this.get('/test-api/posts/1/', function(request) {
return [200, {'Content-Type': 'application/json'}, JSON.stringify(posts[0])];
Expand Down Expand Up @@ -102,25 +97,6 @@ test('Retrieve list of non-paginated records', function() {
});
});

test('Retrieve list of paginated records', function() {
expect(4);

stop();
Ember.run(function() {
store.find('paginatedPost').then(function(response) {
ok(response);

equal(response.get('length'), 3);

var post = response.objectAt(1);
equal(post.get('postTitle'), 'post title 2');
equal(post.get('body'), 'post body 2');

start();
});
});
});

test('Retrieve single record', function() {
expect(3);

Expand Down
221 changes: 221 additions & 0 deletions tests/integration/pagination-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
import Ember from 'ember';
import { test } from 'ember-qunit';
import Pretender from 'pretender';
import startApp from '../helpers/start-app';

var App;
var store;
var server;

var posts = [
{
id: 1,
post_title: 'post title 1',
body: 'post body 1',
comments: []
},
{
id: 2,
post_title: 'post title 2',
body: 'post body 2',
comments: []
},
{
id: 3,
post_title: 'post title 3',
body: 'post body 3',
comments: []
},
{
id: 4,
post_title: 'post title 4',
body: 'post body 4',
comments: []
},
{
id: 5,
post_title: 'post title 5',
body: 'post body 5',
comments: []
},
{
id: 6,
post_title: 'post title 6',
body: 'post body 6',
comments: []
}
];

module('Pagination', {
setup: function() {
App = startApp();

store = App.__container__.lookup('store:main');

// The implementation of the paginated Pretender server is dynamic
// so it can be used with all of the pagination tests. Otherwise,
// different urls would need to be used which would require new
// models.
server = new Pretender(function() {
this.get('/test-api/posts/', function(request) {
var page = 1,
pageSize = 4;

if (request.queryParams.page_size !== undefined) {
pageSize = Number(request.queryParams.page_size).valueOf();
}

var maxPages = posts.length / pageSize;

if (posts.length % pageSize > 0) {
maxPages++;
}

if (request.queryParams.page !== undefined) {
page = Number(request.queryParams.page).valueOf();
if (page > maxPages) {
return [404, {'Content-Type': 'text/html'}, '<h1>Page not found</h1>'];
}
}

var nextPage = page + 1;
var nextUrl = null;
if (nextPage <= maxPages) {
nextUrl = '/test-api/posts/?page=' + nextPage;
}

var previousPage = page - 1;
var previousUrl = null;
if (previousPage >= 1) {
previousUrl = '/test-api/posts/?page=' + previousPage;
}

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)
})];
});
});
},

teardown: function() {
Ember.run(App, 'destroy');
server.shutdown();
}
});

/*
* These integration tests need to use the QUnit.stop() / QUnit.start()
* pattern as described in the following stackoverflow question:
*
* https://stackoverflow.com/questions/26317855/ember-cli-how-to-do-asynchronous-model-unit-testing-with-restadapter
*/
test('Retrieve list of paginated records', function() {
expect(8);

stop();
Ember.run(function() {
store.find('post').then(function(response) {
ok(response);


equal(response.get('length'), 4);

// Test the camelCase and non-camelCase fields of a paginated result.
var post = response.objectAt(1);
equal(post.get('postTitle'), 'post title 2');
equal(post.get('body'), 'post body 2');

// Test the type metadata.
var metadata = store.metadataFor('post');
equal(metadata.count, 6);
equal(metadata.next, 2);
equal(metadata.previous, null);

// No metadata on results when using find without query params.
ok(!response.get('meta'));

start();
});
});
});


test("Type metadata doesn't have previous", function() {
expect(5);

stop();
Ember.run(function() {
store.find('post').then(function(response) {
ok(response);

// Test the type metadata.
var metadata = store.metadataFor('post');
equal(metadata.count, 6);
equal(metadata.next, 2);
equal(metadata.previous, null);

// No metadata on results when using find without query params.
ok(!response.get('meta'));

start();
});
});
});


test("Type metadata doesn't have next", function() {
expect(8);

stop();
Ember.run(function() {
store.find('post', {page: 2}).then(function(response) {
ok(response);
equal(response.get('length'), 2);

// Test the type metadata.
var typeMetadata = store.metadataFor('post');
equal(typeMetadata.count, 6);
equal(typeMetadata.next, null);
equal(typeMetadata.previous, 1);

// Test the results metadata.
var resultsMetadata = response.get('meta');
equal(resultsMetadata.count, 6);
equal(resultsMetadata.next, null);
equal(resultsMetadata.previous, 1);

start();
});
});
});


test("Test page_size query param", function() {
expect(8);

stop();
Ember.run(function() {
store.find('post', {page: 2, page_size: 2}).then(function(response) {
ok(response);
equal(response.get('length'), 2);

// Test the type metadata.
var typeMetadata = store.metadataFor('post');
equal(typeMetadata.count, 6);
equal(typeMetadata.previous, 1);
equal(typeMetadata.next, 3);

// Test the results metadata.
var resultsMetadata = response.get('meta');
equal(resultsMetadata.count, 6);
equal(resultsMetadata.previous, 1);
equal(resultsMetadata.next, 3);

start();
});
});
});
Loading