diff options
Diffstat (limited to 'services/sync/tests/unit/test_collection_getBatched.js')
-rw-r--r-- | services/sync/tests/unit/test_collection_getBatched.js | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/services/sync/tests/unit/test_collection_getBatched.js b/services/sync/tests/unit/test_collection_getBatched.js new file mode 100644 index 000000000..c6523d497 --- /dev/null +++ b/services/sync/tests/unit/test_collection_getBatched.js @@ -0,0 +1,195 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +Cu.import("resource://services-sync/record.js"); +Cu.import("resource://services-sync/service.js"); + +function run_test() { + initTestLogging("Trace"); + Log.repository.getLogger("Sync.Collection").level = Log.Level.Trace; + run_next_test(); +} + +function recordRange(lim, offset, total) { + let res = []; + for (let i = offset; i < Math.min(lim + offset, total); ++i) { + res.push(JSON.stringify({ id: String(i), payload: "test:" + i })); + } + return res.join("\n") + "\n"; +} + +function get_test_collection_info({ totalRecords, batchSize, lastModified, + throwAfter = Infinity, + interruptedAfter = Infinity }) { + let coll = new Collection("http://example.com/test/", WBORecord, Service); + coll.full = true; + let requests = []; + let responses = []; + let sawRecord = false; + coll.get = function() { + ok(!sawRecord); // make sure we call record handler after all requests. + let limit = +this.limit; + let offset = 0; + if (this.offset) { + equal(this.offset.slice(0, 6), "foobar"); + offset = +this.offset.slice(6); + } + requests.push({ + limit, + offset, + spec: this.spec, + headers: Object.assign({}, this.headers) + }); + if (--throwAfter === 0) { + throw "Some Network Error"; + } + let body = recordRange(limit, offset, totalRecords); + this._onProgress.call({ _data: body }); + let response = { + body, + success: true, + status: 200, + headers: {} + }; + if (--interruptedAfter === 0) { + response.success = false; + response.status = 412; + response.body = ""; + } else if (offset + limit < totalRecords) { + // Ensure we're treating this as an opaque string, since the docs say + // it might not be numeric. + response.headers["x-weave-next-offset"] = "foobar" + (offset + batchSize); + } + response.headers["x-last-modified"] = lastModified; + responses.push(response); + return response; + }; + + let records = []; + coll.recordHandler = function(record) { + sawRecord = true; + // ensure records are coming in in the right order + equal(record.id, String(records.length)); + equal(record.payload, "test:" + records.length); + records.push(record); + }; + return { records, responses, requests, coll }; +} + +add_test(function test_success() { + const totalRecords = 11; + const batchSize = 2; + const lastModified = "111111"; + let { records, responses, requests, coll } = get_test_collection_info({ + totalRecords, + batchSize, + lastModified, + }); + let response = coll.getBatched(batchSize); + + equal(requests.length, Math.ceil(totalRecords / batchSize)); + + // records are mostly checked in recordHandler, we just care about the length + equal(records.length, totalRecords); + + // ensure we're returning the last response + equal(responses[responses.length - 1], response); + + // check first separately since its a bit of a special case + ok(!requests[0].headers["x-if-unmodified-since"]); + ok(!requests[0].offset); + equal(requests[0].limit, batchSize); + let expectedOffset = 2; + for (let i = 1; i < requests.length; ++i) { + let req = requests[i]; + equal(req.headers["x-if-unmodified-since"], lastModified); + equal(req.limit, batchSize); + if (i !== requests.length - 1) { + equal(req.offset, expectedOffset); + } + + expectedOffset += batchSize; + } + + // ensure we cleaned up anything that would break further + // use of this collection. + ok(!coll._headers["x-if-unmodified-since"]); + ok(!coll.offset); + ok(!coll.limit || (coll.limit == Infinity)); + + run_next_test(); +}); + +add_test(function test_total_limit() { + _("getBatched respects the (initial) value of the limit property"); + const totalRecords = 100; + const recordLimit = 11; + const batchSize = 2; + const lastModified = "111111"; + let { records, responses, requests, coll } = get_test_collection_info({ + totalRecords, + batchSize, + lastModified, + }); + coll.limit = recordLimit; + let response = coll.getBatched(batchSize); + + equal(requests.length, Math.ceil(recordLimit / batchSize)); + equal(records.length, recordLimit); + + for (let i = 0; i < requests.length; ++i) { + let req = requests[i]; + if (i !== requests.length - 1) { + equal(req.limit, batchSize); + } else { + equal(req.limit, recordLimit % batchSize); + } + } + + equal(coll._limit, recordLimit); + + run_next_test(); +}); + +add_test(function test_412() { + _("We shouldn't record records if we get a 412 in the middle of a batch"); + const totalRecords = 11; + const batchSize = 2; + const lastModified = "111111"; + let { records, responses, requests, coll } = get_test_collection_info({ + totalRecords, + batchSize, + lastModified, + interruptedAfter: 3 + }); + let response = coll.getBatched(batchSize); + + equal(requests.length, 3); + equal(records.length, 0); // record handler shouldn't be called for anything + + // ensure we're returning the last response + equal(responses[responses.length - 1], response); + + ok(!response.success); + equal(response.status, 412); + run_next_test(); +}); + +add_test(function test_get_throws() { + _("We shouldn't record records if get() throws for some reason"); + const totalRecords = 11; + const batchSize = 2; + const lastModified = "111111"; + let { records, responses, requests, coll } = get_test_collection_info({ + totalRecords, + batchSize, + lastModified, + throwAfter: 3 + }); + + throws(() => coll.getBatched(batchSize), "Some Network Error"); + + equal(requests.length, 3); + equal(records.length, 0); + run_next_test(); +}); |