summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/tough-cookie/test/jar_serialization_test.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/tough-cookie/test/jar_serialization_test.js')
-rw-r--r--deps/npm/node_modules/tough-cookie/test/jar_serialization_test.js348
1 files changed, 348 insertions, 0 deletions
diff --git a/deps/npm/node_modules/tough-cookie/test/jar_serialization_test.js b/deps/npm/node_modules/tough-cookie/test/jar_serialization_test.js
new file mode 100644
index 0000000000..277c90c8f4
--- /dev/null
+++ b/deps/npm/node_modules/tough-cookie/test/jar_serialization_test.js
@@ -0,0 +1,348 @@
+/*!
+ * Copyright (c) 2015, Salesforce.com, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of Salesforce.com nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+'use strict';
+var vows = require('vows');
+var assert = require('assert');
+var tough = require('../lib/cookie');
+var Cookie = tough.Cookie;
+var CookieJar = tough.CookieJar;
+var Store = tough.Store;
+var MemoryCookieStore = tough.MemoryCookieStore;
+var VERSION = require('../package.json').version;
+
+var domains = ['example.com','www.example.com','example.net'];
+var paths = ['/','/foo','/foo/bar'];
+
+var isInteger = Number.isInteger || function(value) {
+ // Node 0.10 (still supported) doesn't have Number.isInteger
+ // from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
+ return typeof value === "number" &&
+ isFinite(value) &&
+ Math.floor(value) === value;
+};
+
+function setUp(context) {
+ context.now = new Date();
+ context.nowISO = context.now.toISOString();
+ context.expires = new Date(context.now.getTime() + 86400000);
+
+ var c, domain;
+ context.jar = new CookieJar();
+
+ context.totalCookies = 0;
+
+ // Do paths first since the MemoryCookieStore index is domain at the top
+ // level. This should cause the preservation of creation order in
+ // getAllCookies to be exercised.
+ for (var i = 0; i<paths.length; i++) {
+ var path = paths[i];
+ for (var j = 0; j<domains.length; j++) {
+ domain = domains[j];
+ c = new Cookie({
+ expires: context.expires,
+ domain: domain,
+ path: path,
+ key: 'key',
+ value: 'value'+j+i
+ });
+ context.jar.setCookieSync(c, 'http://'+domain+'/', {now: context.now});
+ context.totalCookies++;
+ }
+ }
+
+ // corner cases
+ domain = 'example.com';
+ var cornerCases = [
+ { expires: 'Infinity', key: 'infExp', value: 'infExp' },
+ { maxAge: 3600, key: 'max', value: 'max' },
+ { expires: context.expires, key: 'flags', value: 'flags',
+ secure: true, httpOnly: true },
+ { expires: context.expires, key: 'honly', value: 'honly',
+ hostOnly: true, domain: 'www.example.org' },
+ ];
+
+ for (var i = 0; i<cornerCases.length; i++) {
+ cornerCases[i].domain = cornerCases[i].domain || 'example.org';
+ cornerCases[i].path = '/';
+ c = new Cookie(cornerCases[i]);
+ context.jar.setCookieSync(c, 'https://www.example.org/', {now: context.now});
+ context.totalCookies++;
+ }
+}
+
+function checkMetadata(serialized) {
+ assert.notEqual(serialized, null);
+ assert.isObject(serialized);
+ assert.equal(serialized.version, 'tough-cookie@'+VERSION);
+ assert.equal(serialized.storeType, 'MemoryCookieStore');
+ assert.typeOf(serialized.rejectPublicSuffixes, 'boolean');
+ assert.isArray(serialized.cookies);
+}
+
+var serializedCookiePropTypes = {
+ 'key': 'string',
+ 'value': 'string',
+ 'expires': 'isoDate', // if "Infinity" it's supposed to be missing
+ 'maxAge': 'intOrInf',
+ 'domain': 'string',
+ 'path': 'string',
+ 'secure': 'boolean',
+ 'httpOnly': 'boolean',
+ 'extensions': 'array', // of strings, technically
+ 'hostOnly': 'boolean',
+ 'pathIsDefault': 'boolean',
+ 'creation': 'isoDate',
+ 'lastAccessed': 'isoDate'
+};
+
+function validateSerializedCookie(cookie) {
+ assert.isObject(cookie);
+ assert.isFalse(cookie instanceof Cookie);
+
+ Object.keys(cookie).forEach(function(prop) {
+ var type = serializedCookiePropTypes[prop];
+ switch(type) {
+ case 'string':
+ case 'boolean':
+ case 'array':
+ case 'number':
+ assert.typeOf(cookie[prop], type);
+ break;
+
+ case 'intOrInf':
+ if (cookie[prop] === 'Infinity' || cookie[prop] === '-Infinity') {
+ assert(true);
+ } else {
+ assert(isInteger(cookie[prop]),
+ "serialized property isn't integer: "+prop);
+ }
+ break;
+
+ case 'isoDate':
+ // rather than a regexp, assert it's parsable and equal
+ var parsed = Date.parse(cookie[prop]);
+ assert(parsed, 'could not parse serialized date property');
+ // assert.equals(cookie[prop], parsed.toISOString());
+ break;
+
+ default:
+ assert.fail("unexpected serialized property: "+prop);
+ }
+ });
+
+}
+
+vows
+ .describe('CookieJar serialization')
+ .addBatch({
+ "Assumptions:": {
+ "serializableProperties all accounted for": function() {
+ var actualKeys = Cookie.serializableProperties.concat([]); // copy
+ actualKeys.sort();
+ var expectedKeys = Object.keys(serializedCookiePropTypes);
+ expectedKeys.sort();
+ assert.deepEqual(actualKeys, expectedKeys);
+ }
+ }
+ })
+ .addBatch({
+ "For Stores without getAllCookies": {
+ topic: function() {
+ var store = new Store();
+ store.synchronous = true;
+ var jar = new CookieJar(store);
+ return jar;
+ },
+ "Cannot call toJSON": function(jar) {
+ assert.throws(function() {
+ jar.toJSON();
+ }, 'getAllCookies is not implemented (therefore jar cannot be serialized)');
+ }
+ }
+ })
+ .addBatch({
+ "For async stores": {
+ topic: function() {
+ var store = new MemoryCookieStore();
+ store.synchronous = false; // pretend it's async
+ var jar = new CookieJar(store);
+ return jar;
+ },
+ "Cannot call toJSON": function(jar) {
+ assert.throws(function() {
+ jar.toJSON();
+ }, 'CookieJar store is not synchronous; use async API instead.');
+ }
+ }
+ })
+ .addBatch({
+ "With a small store": {
+ topic: function() {
+ var now = this.now = new Date();
+ this.jar = new CookieJar();
+ // domain cookie with custom extension
+ var cookie = Cookie.parse('sid=one; domain=example.com; path=/; fubar');
+ this.jar.setCookieSync(cookie, 'http://example.com/', {now: this.now});
+
+ cookie = Cookie.parse('sid=two; domain=example.net; path=/; fubar');
+ this.jar.setCookieSync(cookie, 'http://example.net/', {now: this.now});
+
+ return this.jar;
+ },
+
+ "serialize synchronously": {
+ topic: function(jar) {
+ return jar.serializeSync();
+ },
+ "it gives a serialization with the two cookies": function(data) {
+ checkMetadata(data);
+ assert.equal(data.cookies.length, 2);
+ data.cookies.forEach(function(cookie) {
+ validateSerializedCookie(cookie);
+ });
+ },
+ "then deserialize": {
+ topic: function(data) {
+ return CookieJar.deserializeSync(data);
+ },
+ "memstores are identical": function(newJar) {
+ assert.deepEqual(this.jar.store, newJar.store);
+ }
+ }
+ },
+
+ "serialize asynchronously": {
+ topic: function(jar) {
+ jar.serialize(this.callback);
+ },
+ "it gives a serialization with the two cookies": function(data) {
+ checkMetadata(data);
+ assert.equal(data.cookies.length, 2);
+ data.cookies.forEach(function(cookie) {
+ validateSerializedCookie(cookie);
+ });
+ },
+ "then deserialize": {
+ topic: function(data) {
+ CookieJar.deserialize(data, this.callback);
+ },
+ "memstores are identical": function(newJar) {
+ assert.deepEqual(this.jar.store, newJar.store);
+ }
+ }
+ }
+ }
+ })
+ .addBatch({
+ "With a moderately-sized store": {
+ topic: function() {
+ setUp(this);
+ this.jar.serialize(this.callback);
+ },
+ "has expected metadata": function(err,jsonObj) {
+ assert.isNull(err);
+ assert.equal(jsonObj.version, 'tough-cookie@'+VERSION);
+ assert.isTrue(jsonObj.rejectPublicSuffixes);
+ assert.equal(jsonObj.storeType, 'MemoryCookieStore');
+ },
+ "has a bunch of objects as 'raw' cookies": function(jsonObj) {
+ assert.isArray(jsonObj.cookies);
+ assert.equal(jsonObj.cookies.length, this.totalCookies);
+
+ jsonObj.cookies.forEach(function(cookie) {
+ validateSerializedCookie(cookie);
+
+ if (cookie.key === 'key') {
+ assert.match(cookie.value, /^value\d\d/);
+ }
+
+ if (cookie.key === 'infExp' || cookie.key === 'max') {
+ assert.isUndefined(cookie.expires);
+ } else {
+ assert.strictEqual(cookie.expires, this.expires.toISOString())
+ }
+
+ if (cookie.key === 'max') {
+ assert.strictEqual(cookie.maxAge, 3600);
+ } else {
+ assert.isUndefined(cookie.maxAge);
+ }
+
+ assert.equal(cookie.hostOnly, cookie.key === 'honly');
+
+ if (cookie.key === 'flags') {
+ assert.isTrue(cookie.secure);
+ assert.isTrue(cookie.httpOnly);
+ } else {
+ assert.isUndefined(cookie.secure);
+ assert.isUndefined(cookie.httpOnly);
+ }
+
+ assert.strictEqual(cookie.creation, this.nowISO);
+ assert.strictEqual(cookie.lastAccessed, this.nowISO);
+
+ }, this);
+ },
+
+ "then taking it for a round-trip": {
+ topic: function(jsonObj) {
+ CookieJar.deserialize(jsonObj, this.callback);
+ },
+ "memstore index is identical": function(err,newJar) {
+ assert.deepEqual(newJar.store.idx, this.jar.store.idx);
+ },
+ "then spot-check retrieval": {
+ topic: function(newJar) {
+ newJar.getCookies('http://example.org/', this.callback);
+ },
+ "gets expected cookies": function(results) {
+ assert.isArray(results);
+ assert.equal(results.length, 2);
+
+ results.forEach(function(cookie) {
+ assert.instanceOf(cookie, Cookie);
+
+ if (cookie.key === 'infExp') {
+ assert.strictEqual(cookie.expires, "Infinity");
+ assert.strictEqual(cookie.TTL(this.now), Infinity);
+ } else if (cookie.key === 'max') {
+ assert.strictEqual(cookie.TTL(this.now), 3600*1000);
+ } else {
+ assert.fail('Unexpected cookie key: '+cookie.key);
+ }
+ }.bind(this));
+ }
+ }
+ }
+ }
+ })
+ .export(module);