Bug 1368209 - Add support for `sortindex` and `older` to the mock Sync server. r=tcsc draft
authorKit Cambridge <kit@yakshaving.ninja>
Fri, 27 Oct 2017 17:55:30 -0700
changeset 692425 5a72d3b88da7073d36218dc07279f076873feaaf
parent 692227 3502694e2053f9d8a730f8b8ea1c2e783e58dba3
child 692426 8730a92418c135d8f64eebc404e684269a23864c
child 692825 91a81dccbd167dc1974476ad44318146132166d3
push id87500
push userbmo:kit@mozilla.com
push dateFri, 03 Nov 2017 03:48:59 +0000
reviewerstcsc
bugs1368209
milestone58.0a1
Bug 1368209 - Add support for `sortindex` and `older` to the mock Sync server. r=tcsc MozReview-Commit-ID: 6YI1OEE8x7R
services/sync/tests/unit/head_http_server.js
--- a/services/sync/tests/unit/head_http_server.js
+++ b/services/sync/tests/unit/head_http_server.js
@@ -73,36 +73,39 @@ function ServerWBO(id, initialPayload, m
     return;
   }
 
   if (typeof initialPayload == "object") {
     initialPayload = JSON.stringify(initialPayload);
   }
   this.payload = initialPayload;
   this.modified = modified || new_timestamp();
+  this.sortindex = 0;
 }
 ServerWBO.prototype = {
 
   get data() {
     return JSON.parse(this.payload);
   },
 
   get() {
     return JSON.stringify(this, ["id", "modified", "payload"]);
   },
 
   put(input) {
     input = JSON.parse(input);
     this.payload = input.payload;
     this.modified = new_timestamp();
+    this.sortindex = input.sortindex || 0;
   },
 
   delete() {
     delete this.payload;
     delete this.modified;
+    delete this.sortindex;
   },
 
   // This handler sets `newModified` on the response body if the collection
   // timestamp has changed. This allows wrapper handlers to extract information
   // that otherwise would exist only in the body stream.
   handler() {
     let self = this;
 
@@ -279,79 +282,94 @@ ServerCollection.prototype = {
    */
   remove: function remove(id) {
     delete this._wbos[id];
   },
 
   _inResultSet(wbo, options) {
     return wbo.payload
            && (!options.ids || (options.ids.indexOf(wbo.id) != -1))
-           && (!options.newer || (wbo.modified > options.newer));
+           && (!options.newer || (wbo.modified > options.newer))
+           && (!options.older || (wbo.modified < options.older));
   },
 
   count(options) {
     options = options || {};
     let c = 0;
     for (let wbo of Object.values(this._wbos)) {
       if (wbo.modified && this._inResultSet(wbo, options)) {
         c++;
       }
     }
     return c;
   },
 
   get(options, request) {
-    let result;
+    let data = [];
+    for (let wbo of Object.values(this._wbos)) {
+      if (wbo.modified && this._inResultSet(wbo, options)) {
+        data.push(wbo);
+      }
+    }
+    switch (options.sort) {
+      case "newest":
+        data.sort((a, b) => b.modified - a.modified);
+        break;
+
+      case "oldest":
+        data.sort((a, b) => a.modified - b.modified);
+        break;
+
+      case "index":
+        data.sort((a, b) => b.sortindex - a.sortindex);
+        break;
+
+      default:
+        if (options.sort) {
+          this._log.error("Error: client requesting unknown sort order",
+                          options.sort);
+          throw new Error("Unknown sort order");
+        }
+        // If the client didn't request a sort order, sort newest first,
+        // since `test_history_engine` currently depends on this.
+        data.sort((a, b) => b.modified - a.modified);
+    }
     if (options.full) {
-      let data = [];
-      for (let wbo of Object.values(this._wbos)) {
-        // Drop deleted.
-        if (wbo.modified && this._inResultSet(wbo, options)) {
-          data.push(wbo.get());
-        }
-      }
+      data = data.map(wbo => wbo.get());
       let start = options.offset || 0;
       if (options.limit) {
         let numItemsPastOffset = data.length - start;
         data = data.slice(start, start + options.limit);
         // use options as a backchannel to set x-weave-next-offset
         if (numItemsPastOffset > options.limit) {
           options.nextOffset = start + options.limit;
         }
       } else if (start) {
         data = data.slice(start);
       }
 
       if (request && request.getHeader("accept") == "application/newlines") {
         this._log.error("Error: client requesting application/newlines content");
         throw new Error("This server should not serve application/newlines content");
-      } else {
-        result = JSON.stringify(data);
       }
 
       // Use options as a backchannel to report count.
       options.recordCount = data.length;
     } else {
-      let data = [];
-      for (let [id, wbo] of Object.entries(this._wbos)) {
-        if (this._inResultSet(wbo, options)) {
-          data.push(id);
-        }
-      }
+      data = data.map(wbo => wbo.id);
       let start = options.offset || 0;
       if (options.limit) {
         data = data.slice(start, start + options.limit);
         options.nextOffset = start + options.limit;
       } else if (start) {
         data = data.slice(start);
       }
-      result = JSON.stringify(data);
       options.recordCount = data.length;
     }
-    return result;
+    return JSON.stringify(data);
   },
 
   post(input) {
     input = JSON.parse(input);
     let success = [];
     let failed = {};
 
     // This will count records where we have an existing ServerWBO
@@ -363,16 +381,17 @@ ServerCollection.prototype = {
         this._log.debug("Creating WBO " + JSON.stringify(record.id) +
                         " on the fly.");
         wbo = new ServerWBO(record.id);
         this.insertWBO(wbo);
       }
       if (wbo) {
         wbo.payload = record.payload;
         wbo.modified = new_timestamp();
+        wbo.sortindex = record.sortindex || 0;
         success.push(record.id);
       } else {
         failed[record.id] = "no wbo configured";
       }
     }
     return {modified: new_timestamp(),
             success,
             failed};
@@ -421,16 +440,19 @@ ServerCollection.prototype = {
           response.bodyOutputStream.write(body, body.length);
           return;
         }
         options.ids = options.ids.split(",");
       }
       if (options.newer) {
         options.newer = parseFloat(options.newer);
       }
+      if (options.older) {
+        options.older = parseFloat(options.older);
+      }
       if (options.limit) {
         options.limit = parseInt(options.limit, 10);
       }
       if (options.offset) {
         options.offset = parseInt(options.offset, 10);
       }
 
       switch (request.method) {