Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* Any copyright is dedicated to the Public Domain. |
michael@0 | 2 | http://creativecommons.org/publicdomain/zero/1.0/ */ |
michael@0 | 3 | |
michael@0 | 4 | Cu.import("resource://services-sync/util.js"); |
michael@0 | 5 | |
michael@0 | 6 | function run_test() { |
michael@0 | 7 | Log.repository.getLogger("Sync.Test.Server").level = Log.Level.Trace; |
michael@0 | 8 | initTestLogging(); |
michael@0 | 9 | run_next_test(); |
michael@0 | 10 | } |
michael@0 | 11 | |
michael@0 | 12 | add_test(function test_creation() { |
michael@0 | 13 | // Explicit callback for this one. |
michael@0 | 14 | let server = new SyncServer({ |
michael@0 | 15 | __proto__: SyncServerCallback, |
michael@0 | 16 | }); |
michael@0 | 17 | do_check_true(!!server); // Just so we have a check. |
michael@0 | 18 | server.start(null, function () { |
michael@0 | 19 | _("Started on " + server.port); |
michael@0 | 20 | server.stop(run_next_test); |
michael@0 | 21 | }); |
michael@0 | 22 | }); |
michael@0 | 23 | |
michael@0 | 24 | add_test(function test_url_parsing() { |
michael@0 | 25 | let server = new SyncServer(); |
michael@0 | 26 | |
michael@0 | 27 | // Check that we can parse a WBO URI. |
michael@0 | 28 | let parts = server.pathRE.exec("/1.1/johnsmith/storage/crypto/keys"); |
michael@0 | 29 | let [all, version, username, first, rest] = parts; |
michael@0 | 30 | do_check_eq(all, "/1.1/johnsmith/storage/crypto/keys"); |
michael@0 | 31 | do_check_eq(version, "1.1"); |
michael@0 | 32 | do_check_eq(username, "johnsmith"); |
michael@0 | 33 | do_check_eq(first, "storage"); |
michael@0 | 34 | do_check_eq(rest, "crypto/keys"); |
michael@0 | 35 | do_check_eq(null, server.pathRE.exec("/nothing/else")); |
michael@0 | 36 | |
michael@0 | 37 | // Check that we can parse a collection URI. |
michael@0 | 38 | parts = server.pathRE.exec("/1.1/johnsmith/storage/crypto"); |
michael@0 | 39 | let [all, version, username, first, rest] = parts; |
michael@0 | 40 | do_check_eq(all, "/1.1/johnsmith/storage/crypto"); |
michael@0 | 41 | do_check_eq(version, "1.1"); |
michael@0 | 42 | do_check_eq(username, "johnsmith"); |
michael@0 | 43 | do_check_eq(first, "storage"); |
michael@0 | 44 | do_check_eq(rest, "crypto"); |
michael@0 | 45 | |
michael@0 | 46 | // We don't allow trailing slash on storage URI. |
michael@0 | 47 | parts = server.pathRE.exec("/1.1/johnsmith/storage/"); |
michael@0 | 48 | do_check_eq(parts, undefined); |
michael@0 | 49 | |
michael@0 | 50 | // storage alone is a valid request. |
michael@0 | 51 | parts = server.pathRE.exec("/1.1/johnsmith/storage"); |
michael@0 | 52 | let [all, version, username, first, rest] = parts; |
michael@0 | 53 | do_check_eq(all, "/1.1/johnsmith/storage"); |
michael@0 | 54 | do_check_eq(version, "1.1"); |
michael@0 | 55 | do_check_eq(username, "johnsmith"); |
michael@0 | 56 | do_check_eq(first, "storage"); |
michael@0 | 57 | do_check_eq(rest, undefined); |
michael@0 | 58 | |
michael@0 | 59 | parts = server.storageRE.exec("storage"); |
michael@0 | 60 | let [all, storage, collection, id] = parts; |
michael@0 | 61 | do_check_eq(all, "storage"); |
michael@0 | 62 | do_check_eq(collection, undefined); |
michael@0 | 63 | |
michael@0 | 64 | run_next_test(); |
michael@0 | 65 | }); |
michael@0 | 66 | |
michael@0 | 67 | Cu.import("resource://services-common/rest.js"); |
michael@0 | 68 | function localRequest(server, path) { |
michael@0 | 69 | _("localRequest: " + path); |
michael@0 | 70 | let url = server.baseURI.substr(0, server.baseURI.length - 1) + path; |
michael@0 | 71 | _("url: " + url); |
michael@0 | 72 | return new RESTRequest(url); |
michael@0 | 73 | } |
michael@0 | 74 | |
michael@0 | 75 | add_test(function test_basic_http() { |
michael@0 | 76 | let server = new SyncServer(); |
michael@0 | 77 | server.registerUser("john", "password"); |
michael@0 | 78 | do_check_true(server.userExists("john")); |
michael@0 | 79 | server.start(null, function () { |
michael@0 | 80 | _("Started on " + server.port); |
michael@0 | 81 | Utils.nextTick(function () { |
michael@0 | 82 | let req = localRequest(server, "/1.1/john/storage/crypto/keys"); |
michael@0 | 83 | _("req is " + req); |
michael@0 | 84 | req.get(function (err) { |
michael@0 | 85 | do_check_eq(null, err); |
michael@0 | 86 | Utils.nextTick(function () { |
michael@0 | 87 | server.stop(run_next_test); |
michael@0 | 88 | }); |
michael@0 | 89 | }); |
michael@0 | 90 | }); |
michael@0 | 91 | }); |
michael@0 | 92 | }); |
michael@0 | 93 | |
michael@0 | 94 | add_test(function test_info_collections() { |
michael@0 | 95 | let server = new SyncServer({ |
michael@0 | 96 | __proto__: SyncServerCallback |
michael@0 | 97 | }); |
michael@0 | 98 | function responseHasCorrectHeaders(r) { |
michael@0 | 99 | do_check_eq(r.status, 200); |
michael@0 | 100 | do_check_eq(r.headers["content-type"], "application/json"); |
michael@0 | 101 | do_check_true("x-weave-timestamp" in r.headers); |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | server.registerUser("john", "password"); |
michael@0 | 105 | server.start(null, function () { |
michael@0 | 106 | Utils.nextTick(function () { |
michael@0 | 107 | let req = localRequest(server, "/1.1/john/info/collections"); |
michael@0 | 108 | req.get(function (err) { |
michael@0 | 109 | // Initial info/collections fetch is empty. |
michael@0 | 110 | do_check_eq(null, err); |
michael@0 | 111 | responseHasCorrectHeaders(this.response); |
michael@0 | 112 | |
michael@0 | 113 | do_check_eq(this.response.body, "{}"); |
michael@0 | 114 | Utils.nextTick(function () { |
michael@0 | 115 | // When we PUT something to crypto/keys, "crypto" appears in the response. |
michael@0 | 116 | function cb(err) { |
michael@0 | 117 | do_check_eq(null, err); |
michael@0 | 118 | responseHasCorrectHeaders(this.response); |
michael@0 | 119 | let putResponseBody = this.response.body; |
michael@0 | 120 | _("PUT response body: " + JSON.stringify(putResponseBody)); |
michael@0 | 121 | |
michael@0 | 122 | req = localRequest(server, "/1.1/john/info/collections"); |
michael@0 | 123 | req.get(function (err) { |
michael@0 | 124 | do_check_eq(null, err); |
michael@0 | 125 | responseHasCorrectHeaders(this.response); |
michael@0 | 126 | let expectedColl = server.getCollection("john", "crypto"); |
michael@0 | 127 | do_check_true(!!expectedColl); |
michael@0 | 128 | let modified = expectedColl.timestamp; |
michael@0 | 129 | do_check_true(modified > 0); |
michael@0 | 130 | do_check_eq(putResponseBody, modified); |
michael@0 | 131 | do_check_eq(JSON.parse(this.response.body).crypto, modified); |
michael@0 | 132 | Utils.nextTick(function () { |
michael@0 | 133 | server.stop(run_next_test); |
michael@0 | 134 | }); |
michael@0 | 135 | }); |
michael@0 | 136 | } |
michael@0 | 137 | let payload = JSON.stringify({foo: "bar"}); |
michael@0 | 138 | localRequest(server, "/1.1/john/storage/crypto/keys").put(payload, cb); |
michael@0 | 139 | }); |
michael@0 | 140 | }); |
michael@0 | 141 | }); |
michael@0 | 142 | }); |
michael@0 | 143 | }); |
michael@0 | 144 | |
michael@0 | 145 | add_test(function test_storage_request() { |
michael@0 | 146 | let keysURL = "/1.1/john/storage/crypto/keys?foo=bar"; |
michael@0 | 147 | let foosURL = "/1.1/john/storage/crypto/foos"; |
michael@0 | 148 | let storageURL = "/1.1/john/storage"; |
michael@0 | 149 | |
michael@0 | 150 | let server = new SyncServer(); |
michael@0 | 151 | let creation = server.timestamp(); |
michael@0 | 152 | server.registerUser("john", "password"); |
michael@0 | 153 | |
michael@0 | 154 | server.createContents("john", { |
michael@0 | 155 | crypto: {foos: {foo: "bar"}} |
michael@0 | 156 | }); |
michael@0 | 157 | let coll = server.user("john").collection("crypto"); |
michael@0 | 158 | do_check_true(!!coll); |
michael@0 | 159 | |
michael@0 | 160 | _("We're tracking timestamps."); |
michael@0 | 161 | do_check_true(coll.timestamp >= creation); |
michael@0 | 162 | |
michael@0 | 163 | function retrieveWBONotExists(next) { |
michael@0 | 164 | let req = localRequest(server, keysURL); |
michael@0 | 165 | req.get(function (err) { |
michael@0 | 166 | _("Body is " + this.response.body); |
michael@0 | 167 | _("Modified is " + this.response.newModified); |
michael@0 | 168 | do_check_eq(null, err); |
michael@0 | 169 | do_check_eq(this.response.status, 404); |
michael@0 | 170 | do_check_eq(this.response.body, "Not found"); |
michael@0 | 171 | Utils.nextTick(next); |
michael@0 | 172 | }); |
michael@0 | 173 | } |
michael@0 | 174 | function retrieveWBOExists(next) { |
michael@0 | 175 | let req = localRequest(server, foosURL); |
michael@0 | 176 | req.get(function (err) { |
michael@0 | 177 | _("Body is " + this.response.body); |
michael@0 | 178 | _("Modified is " + this.response.newModified); |
michael@0 | 179 | let parsedBody = JSON.parse(this.response.body); |
michael@0 | 180 | do_check_eq(parsedBody.id, "foos"); |
michael@0 | 181 | do_check_eq(parsedBody.modified, coll.wbo("foos").modified); |
michael@0 | 182 | do_check_eq(JSON.parse(parsedBody.payload).foo, "bar"); |
michael@0 | 183 | Utils.nextTick(next); |
michael@0 | 184 | }); |
michael@0 | 185 | } |
michael@0 | 186 | function deleteWBONotExists(next) { |
michael@0 | 187 | let req = localRequest(server, keysURL); |
michael@0 | 188 | server.callback.onItemDeleted = function (username, collection, wboID) { |
michael@0 | 189 | do_throw("onItemDeleted should not have been called."); |
michael@0 | 190 | }; |
michael@0 | 191 | |
michael@0 | 192 | req.delete(function (err) { |
michael@0 | 193 | _("Body is " + this.response.body); |
michael@0 | 194 | _("Modified is " + this.response.newModified); |
michael@0 | 195 | do_check_eq(this.response.status, 200); |
michael@0 | 196 | delete server.callback.onItemDeleted; |
michael@0 | 197 | Utils.nextTick(next); |
michael@0 | 198 | }); |
michael@0 | 199 | } |
michael@0 | 200 | function deleteWBOExists(next) { |
michael@0 | 201 | let req = localRequest(server, foosURL); |
michael@0 | 202 | server.callback.onItemDeleted = function (username, collection, wboID) { |
michael@0 | 203 | _("onItemDeleted called for " + collection + "/" + wboID); |
michael@0 | 204 | delete server.callback.onItemDeleted; |
michael@0 | 205 | do_check_eq(username, "john"); |
michael@0 | 206 | do_check_eq(collection, "crypto"); |
michael@0 | 207 | do_check_eq(wboID, "foos"); |
michael@0 | 208 | Utils.nextTick(next); |
michael@0 | 209 | }; |
michael@0 | 210 | |
michael@0 | 211 | req.delete(function (err) { |
michael@0 | 212 | _("Body is " + this.response.body); |
michael@0 | 213 | _("Modified is " + this.response.newModified); |
michael@0 | 214 | do_check_eq(this.response.status, 200); |
michael@0 | 215 | }); |
michael@0 | 216 | } |
michael@0 | 217 | function deleteStorage(next) { |
michael@0 | 218 | _("Testing DELETE on /storage."); |
michael@0 | 219 | let now = server.timestamp(); |
michael@0 | 220 | _("Timestamp: " + now); |
michael@0 | 221 | let req = localRequest(server, storageURL); |
michael@0 | 222 | req.delete(function (err) { |
michael@0 | 223 | _("Body is " + this.response.body); |
michael@0 | 224 | _("Modified is " + this.response.newModified); |
michael@0 | 225 | let parsedBody = JSON.parse(this.response.body); |
michael@0 | 226 | do_check_true(parsedBody >= now); |
michael@0 | 227 | do_check_empty(server.users["john"].collections); |
michael@0 | 228 | Utils.nextTick(next); |
michael@0 | 229 | }); |
michael@0 | 230 | } |
michael@0 | 231 | function getStorageFails(next) { |
michael@0 | 232 | _("Testing that GET on /storage fails."); |
michael@0 | 233 | let req = localRequest(server, storageURL); |
michael@0 | 234 | req.get(function (err) { |
michael@0 | 235 | do_check_eq(this.response.status, 405); |
michael@0 | 236 | do_check_eq(this.response.headers["allow"], "DELETE"); |
michael@0 | 237 | Utils.nextTick(next); |
michael@0 | 238 | }); |
michael@0 | 239 | } |
michael@0 | 240 | function getMissingCollectionWBO(next) { |
michael@0 | 241 | _("Testing that fetching a WBO from an on-existent collection 404s."); |
michael@0 | 242 | let req = localRequest(server, storageURL + "/foobar/baz"); |
michael@0 | 243 | req.get(function (err) { |
michael@0 | 244 | do_check_eq(this.response.status, 404); |
michael@0 | 245 | Utils.nextTick(next); |
michael@0 | 246 | }); |
michael@0 | 247 | } |
michael@0 | 248 | |
michael@0 | 249 | server.start(null, |
michael@0 | 250 | Async.chain( |
michael@0 | 251 | retrieveWBONotExists, |
michael@0 | 252 | retrieveWBOExists, |
michael@0 | 253 | deleteWBOExists, |
michael@0 | 254 | deleteWBONotExists, |
michael@0 | 255 | getStorageFails, |
michael@0 | 256 | getMissingCollectionWBO, |
michael@0 | 257 | deleteStorage, |
michael@0 | 258 | server.stop.bind(server), |
michael@0 | 259 | run_next_test |
michael@0 | 260 | )); |
michael@0 | 261 | }); |
michael@0 | 262 | |
michael@0 | 263 | add_test(function test_x_weave_records() { |
michael@0 | 264 | let server = new SyncServer(); |
michael@0 | 265 | server.registerUser("john", "password"); |
michael@0 | 266 | |
michael@0 | 267 | server.createContents("john", { |
michael@0 | 268 | crypto: {foos: {foo: "bar"}, |
michael@0 | 269 | bars: {foo: "baz"}} |
michael@0 | 270 | }); |
michael@0 | 271 | server.start(null, function () { |
michael@0 | 272 | let wbo = localRequest(server, "/1.1/john/storage/crypto/foos"); |
michael@0 | 273 | wbo.get(function (err) { |
michael@0 | 274 | // WBO fetches don't have one. |
michael@0 | 275 | do_check_false("x-weave-records" in this.response.headers); |
michael@0 | 276 | let col = localRequest(server, "/1.1/john/storage/crypto"); |
michael@0 | 277 | col.get(function (err) { |
michael@0 | 278 | // Collection fetches do. |
michael@0 | 279 | do_check_eq(this.response.headers["x-weave-records"], "2"); |
michael@0 | 280 | server.stop(run_next_test); |
michael@0 | 281 | }); |
michael@0 | 282 | }); |
michael@0 | 283 | }); |
michael@0 | 284 | }); |