#1071560: indexing paging is broken.

From: Damien Tournoud <damien@commerceguys.com>


---
 node_resource.inc                         |   12 ++++-----
 user_resource.inc                         |    8 +++---
 functional/ServicesResourceNodeTests.test |   40 +++++++++++++++++++++++++++--
 3 files changed, 47 insertions(+), 13 deletions(-)

diff --git resources/node_resource.inc resources/node_resource.inc
index 3f4ce53..ba58b4b 100644
--- resources/node_resource.inc
+++ resources/node_resource.inc
@@ -83,7 +83,7 @@ function _node_resource_definition() {
             'optional' => TRUE,
             'type' => 'int',
             'description' => 'The zero-based index of the page to get, defaults to 0.',
-            'default value' => 1,
+            'default value' => 0,
             'source' => array('param' => 'page'),
           ),
           array(
@@ -302,14 +302,13 @@ function _node_resource_delete($nid) {
  *     - Is there an easier syntax we can define which can make the urls
  *       for index requests more straightforward?
  **/
-function _node_resource_index($page = 1, $fields = '*', $parameters = array()) {
+function _node_resource_index($page = 0, $fields = '*', $parameters = array()) {
   $node_select = db_select('node', 'n')
-    ->extend('PagerDefault')
     ->addTag('node_access')
     ->orderBy('sticky', 'DESC')
     ->orderBy('created', 'DESC')
-    ->limit($page * 20);
-    
+    ->range($page * 20, 20);
+
   if ($fields == '*') {
     $node_select->fields('n');
   } else {
@@ -322,7 +321,8 @@ function _node_resource_index($page = 1, $fields = '*', $parameters = array()) {
   }
 
   $result = $node_select->execute();
-  
+
+  $nodes = array();
   foreach($result as $node) {
     if ($uri = services_resource_uri(array('node', $node->nid))) {
       $node->uri = $uri;
diff --git resources/user_resource.inc resources/user_resource.inc
index 69e1616..5303727 100644
--- resources/user_resource.inc
+++ resources/user_resource.inc
@@ -92,7 +92,7 @@ function _user_resource_definition() {
             'optional' => TRUE,
             'type' => 'int',
             'description' => 'The zero-based index of the page to get, defaults to 0.',
-            'default value' => 1,
+            'default value' => 0,
             'source' => array('param' => 'page'),
           ),
           array(
@@ -401,8 +401,8 @@ function _user_resource_logout() {
  *
  * @see _node_resource_index() for more notes
  **/
-function _user_resource_index($page = 1, $fields = '*', $parameters = array()) {
-  $user_select = db_select('users', 'u')->extend('PagerDefault');
+function _user_resource_index($page = 0, $fields = '*', $parameters = array()) {
+  $user_select = db_select('users', 'u');
   if($fields == '*') { 
     $user_select->fields('u');  
   } else {
@@ -410,7 +410,7 @@ function _user_resource_index($page = 1, $fields = '*', $parameters = array()) {
     $user_select->fields('u', $fields);
   }
   $user_select->orderBy('created', 'DESC');
-  $user_select->limit($page * 20);
+  $user_select->range($page * 20, 20);
   $result = $user_select->execute();
   foreach($result as $user) {  
     if ($uri = services_resource_uri(array('user', $user->uid))) {
diff --git tests/functional/ServicesResourceNodeTests.test tests/functional/ServicesResourceNodeTests.test
index 40ba965..106ae88 100644
--- tests/functional/ServicesResourceNodeTests.test
+++ tests/functional/ServicesResourceNodeTests.test
@@ -51,9 +51,43 @@ class ServicesResourceNodetests extends ServicesWebTestCase {
     ));
     $this->drupalLogin($this->privilegedUser);
 
-    $node = $this->drupalCreateNode();
-    $responseArray = $this->servicesGet($this->endpoint->path . '/node');
-    $this->assertTrue($node->title == $responseArray['body'][0]->title, t('Successfully received Node info'), 'NodeResource: Index');
+    // Create a set of nodes. The node resource returns 20 returns at a time,
+    // so we create two pages and a half worth.
+    $nodes = array();
+    $count = 50;
+    for ($i = 0; $i < $count; $i++) {
+      $node = $this->drupalCreateNode();
+      $nodes[$node->nid] = $node;
+    }
+
+    // Get the content.
+    $page_count = ceil(count($nodes) / 20);
+    $retrieved_nodes = array();
+    for ($page = 0; $page < $page_count; $page++) {
+      $responseArray = $this->servicesGet($this->endpoint->path . '/node', array('page' => $page));
+      $this->assertTrue(count($responseArray['body']) <= 20, t('Correct number of items returned'));
+
+      // Store the returned node IDs.
+      foreach ($responseArray['body'] as $node) {
+        if (isset($retrieved_nodes[$node->nid])) {
+          $this->fail(t('Duplicate node @nid returned.', array('@nid' => $node->nid)));
+        }
+        $retrieved_nodes[$node->nid] = TRUE;
+
+        $this->assertTrue($nodes[$node->nid]->title == $node->title, t('Successfully received Node info'), 'NodeResource: Index');
+      }
+    }
+
+    // We should have got all the nodes.
+    $expected_nids = array_keys($nodes);
+    sort($expected_nids);
+    $retrieved_nids = array_keys($retrieved_nodes);
+    sort($retrieved_nids);
+    $this->assertEqual($expected_nids, $retrieved_nids, t('Retrieved all nodes'));
+
+    // The n+1 page should be empty.
+    $responseArray = $this->servicesGet($this->endpoint->path . '/node', array('page' => $page_count + 1));
+    $this->assertEqual(count($responseArray['body']), 0, t('The n+1 page is empty'));
   }
 
   /**
