зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1069816: add unit tests for the GoogleImporter class. r=abr
This commit is contained in:
Родитель
9aa1b91cc1
Коммит
0b4d324d7e
|
@ -1,11 +1,16 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
fixtures/google_auth.txt
|
||||
fixtures/google_contacts.txt
|
||||
fixtures/google_token.txt
|
||||
google_service.sjs
|
||||
head.js
|
||||
loop_fxa.sjs
|
||||
../../../../base/content/test/general/browser_fxa_oauth.html
|
||||
|
||||
[browser_CardDavImporter.js]
|
||||
[browser_fxa_login.js]
|
||||
[browser_GoogleImporter.js]
|
||||
skip-if = e10s
|
||||
[browser_loop_fxa_server.js]
|
||||
[browser_LoopContacts.js]
|
||||
|
|
|
@ -3,46 +3,6 @@
|
|||
|
||||
const {CardDavImporter} = Cu.import("resource:///modules/loop/CardDavImporter.jsm", {});
|
||||
|
||||
const mockDb = {
|
||||
_store: { },
|
||||
_next_guid: 1,
|
||||
|
||||
add: function(details, callback) {
|
||||
if (!("id" in details)) {
|
||||
callback(new Error("No 'id' field present"));
|
||||
return;
|
||||
}
|
||||
details._guid = this._next_guid++;
|
||||
this._store[details._guid] = details;
|
||||
callback(null, details);
|
||||
},
|
||||
remove: function(guid, callback) {
|
||||
if (!guid in this._store) {
|
||||
callback(new Error("Could not find _guid '" + guid + "' in database"));
|
||||
return;
|
||||
}
|
||||
delete this._store[guid];
|
||||
callback(null);
|
||||
},
|
||||
get: function(guid, callback) {
|
||||
callback(null, this._store[guid]);
|
||||
},
|
||||
getByServiceId: function(serviceId, callback) {
|
||||
for (let guid in this._store) {
|
||||
if (serviceId === this._store[guid].id) {
|
||||
callback(null, this._store[guid]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback(null, null);
|
||||
},
|
||||
removeAll: function(callback) {
|
||||
this._store = {};
|
||||
this._next_guid = 1;
|
||||
callback(null);
|
||||
}
|
||||
};
|
||||
|
||||
const kAuth = {
|
||||
"method": "basic",
|
||||
"user": "username",
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const {GoogleImporter} = Cu.import("resource:///modules/loop/GoogleImporter.jsm", {});
|
||||
|
||||
let importer = new GoogleImporter();
|
||||
|
||||
function promiseImport() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
importer.startImport({}, function(err, stats) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(stats);
|
||||
}
|
||||
}, mockDb, window);
|
||||
});
|
||||
}
|
||||
|
||||
add_task(function* test_GoogleImport() {
|
||||
let stats;
|
||||
// An error may throw and the test will fail when that happens.
|
||||
stats = yield promiseImport();
|
||||
|
||||
// Assert the world.
|
||||
Assert.equal(stats.total, 5, "Five contacts should get processed");
|
||||
Assert.equal(stats.success, 5, "Five contacts should be imported");
|
||||
|
||||
yield promiseImport();
|
||||
Assert.equal(Object.keys(mockDb._store).length, 5, "Database should contain only five contact after reimport");
|
||||
|
||||
let c = mockDb._store[mockDb._next_guid - 5];
|
||||
Assert.equal(c.name[0], "John Smith", "Full name should match");
|
||||
Assert.equal(c.givenName[0], "John", "Given name should match");
|
||||
Assert.equal(c.familyName[0], "Smith", "Family name should match");
|
||||
Assert.equal(c.email[0].type, "other", "Email type should match");
|
||||
Assert.equal(c.email[0].value, "john.smith@example.com", "Email should match");
|
||||
Assert.equal(c.email[0].pref, true, "Pref should match");
|
||||
Assert.equal(c.category[0], "google", "Category should match");
|
||||
Assert.equal(c.id, "http://www.google.com/m8/feeds/contacts/tester%40mochi.com/base/0", "UID should match and be scoped to provider");
|
||||
|
||||
c = mockDb._store[mockDb._next_guid - 4];
|
||||
Assert.equal(c.name[0], "Jane Smith", "Full name should match");
|
||||
Assert.equal(c.givenName[0], "Jane", "Given name should match");
|
||||
Assert.equal(c.familyName[0], "Smith", "Family name should match");
|
||||
Assert.equal(c.email[0].type, "other", "Email type should match");
|
||||
Assert.equal(c.email[0].value, "jane.smith@example.com", "Email should match");
|
||||
Assert.equal(c.email[0].pref, true, "Pref should match");
|
||||
Assert.equal(c.category[0], "google", "Category should match");
|
||||
Assert.equal(c.id, "http://www.google.com/m8/feeds/contacts/tester%40mochi.com/base/1", "UID should match and be scoped to provider");
|
||||
|
||||
c = mockDb._store[mockDb._next_guid - 3];
|
||||
Assert.equal(c.name[0], "Davy Randall Jones", "Full name should match");
|
||||
Assert.equal(c.givenName[0], "Davy Randall", "Given name should match");
|
||||
Assert.equal(c.familyName[0], "Jones", "Family name should match");
|
||||
Assert.equal(c.email[0].type, "other", "Email type should match");
|
||||
Assert.equal(c.email[0].value, "davy.jones@example.com", "Email should match");
|
||||
Assert.equal(c.email[0].pref, true, "Pref should match");
|
||||
Assert.equal(c.category[0], "google", "Category should match");
|
||||
Assert.equal(c.id, "http://www.google.com/m8/feeds/contacts/tester%40mochi.com/base/2", "UID should match and be scoped to provider");
|
||||
|
||||
c = mockDb._store[mockDb._next_guid - 2];
|
||||
Assert.equal(c.name[0], "noname@example.com", "Full name should match");
|
||||
Assert.equal(c.email[0].type, "other", "Email type should match");
|
||||
Assert.equal(c.email[0].value, "noname@example.com", "Email should match");
|
||||
Assert.equal(c.email[0].pref, true, "Pref should match");
|
||||
Assert.equal(c.category[0], "google", "Category should match");
|
||||
Assert.equal(c.id, "http://www.google.com/m8/feeds/contacts/tester%40mochi.com/base/3", "UID should match and be scoped to provider");
|
||||
|
||||
c = mockDb._store[mockDb._next_guid - 1];
|
||||
Assert.equal(c.name[0], "lycnix", "Full name should match");
|
||||
Assert.equal(c.email[0].type, "other", "Email type should match");
|
||||
Assert.equal(c.email[0].value, "lycnix", "Email should match");
|
||||
Assert.equal(c.email[0].pref, true, "Pref should match");
|
||||
Assert.equal(c.category[0], "google", "Category should match");
|
||||
Assert.equal(c.id, "http://www.google.com/m8/feeds/contacts/tester%40mochi.com/base/7", "UID should match and be scoped to provider");
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>Success code=test-code</title></head>
|
||||
<body>Le Code.</body>
|
||||
</html>
|
|
@ -0,0 +1,94 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<feed gd:etag="W/"DUQNRHc8cCt7I2A9XRdSF04."" xmlns="http://www.w3.org/2005/Atom" xmlns:batch="http://schemas.google.com/gdata/batch" xmlns:gContact="http://schemas.google.com/contact/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">
|
||||
<id>tester@mochi.com</id>
|
||||
<updated>2014-09-26T13:16:35.978Z</updated>
|
||||
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
|
||||
<title>Mochi Tester's Contacts</title>
|
||||
<link href="http://www.google.com/" rel="alternate" type="text/html"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full" rel="http://schemas.google.com/g/2005#post" type="application/atom+xml"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full/batch" rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full?max-results=25" rel="self" type="application/atom+xml"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full?start-index=26&max-results=25" rel="next" type="application/atom+xml"/>
|
||||
<author>
|
||||
<name>Mochi Tester</name>
|
||||
<email>tester@mochi.com</email>
|
||||
</author>
|
||||
<generator uri="http://www.google.com/m8/feeds" version="1.0">Contacts</generator>
|
||||
<openSearch:totalResults>25</openSearch:totalResults>
|
||||
<openSearch:startIndex>1</openSearch:startIndex>
|
||||
<openSearch:itemsPerPage>10000000</openSearch:itemsPerPage>
|
||||
<entry gd:etag=""R3YyejRVLit7I2A9WhJWEkkNQwc."">
|
||||
<id>http://www.google.com/m8/feeds/contacts/tester%40mochi.com/base/0</id>
|
||||
<updated>2012-08-17T23:50:36.892Z</updated>
|
||||
<app:edited xmlns:app="http://www.w3.org/2007/app">2012-08-17T23:50:36.892Z</app:edited>
|
||||
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
|
||||
<title>John Smith</title>
|
||||
<link gd:etag=""Ug92D34SfCt7I2BmLHJTRgVzTlgrJXEAU08."" href="https://www.google.com/m8/feeds/photos/media/tester%40mochi.com/0" rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full/0" rel="self" type="application/atom+xml"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full/0" rel="edit" type="application/atom+xml"/>
|
||||
<gd:name>
|
||||
<gd:fullName>John Smith</gd:fullName>
|
||||
<gd:givenName>John</gd:givenName>
|
||||
<gd:familyName>Smith</gd:familyName>
|
||||
</gd:name>
|
||||
<gd:email address="john.smith@example.com" primary="true" rel="http://schemas.google.com/g/2005#other"/>
|
||||
<gContact:website href="http://www.google.com/profiles/109576547678240773721" rel="profile"/>
|
||||
</entry>
|
||||
<entry gd:etag=""R3YyejRVLit7I2A9WhJWEkkNQwc."">
|
||||
<id>http://www.google.com/m8/feeds/contacts/tester%40mochi.com/base/1</id>
|
||||
<updated>2012-08-17T23:50:36.892Z</updated>
|
||||
<app:edited xmlns:app="http://www.w3.org/2007/app">2012-08-17T23:50:36.892Z</app:edited>
|
||||
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
|
||||
<title>Jane Smith</title>
|
||||
<link gd:etag=""WA9BY1xFWit7I2BhLEkieCxLHEYTGCYuNxo."" href="https://www.google.com/m8/feeds/photos/media/tester%40mochi.com/1" rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full/1" rel="self" type="application/atom+xml"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full/1" rel="edit" type="application/atom+xml"/>
|
||||
<gd:name>
|
||||
<gd:fullName>Jane Smith</gd:fullName>
|
||||
<gd:givenName>Jane</gd:givenName>
|
||||
<gd:familyName>Smith</gd:familyName>
|
||||
</gd:name>
|
||||
<gd:email address="jane.smith@example.com" primary="true" rel="http://schemas.google.com/g/2005#other"/>
|
||||
<gContact:website href="http://www.google.com/profiles/112886528199784431028" rel="profile"/>
|
||||
</entry>
|
||||
<entry gd:etag=""R3YyejRVLit7I2A9WhJWEkkNQwc."">
|
||||
<id>http://www.google.com/m8/feeds/contacts/tester%40mochi.com/base/2</id>
|
||||
<updated>2012-08-17T23:50:36.892Z</updated>
|
||||
<app:edited xmlns:app="http://www.w3.org/2007/app">2012-08-17T23:50:36.892Z</app:edited>
|
||||
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
|
||||
<title>Davy Randall Jones</title>
|
||||
<link gd:etag=""KiV2PkYRfCt7I2BuD1AzEBFxD1VcGjwBUyA."" href="https://www.google.com/m8/feeds/photos/media/tester%40mochi.com/2" rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full/2" rel="self" type="application/atom+xml"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full/2" rel="edit" type="application/atom+xml"/>
|
||||
<gd:name>
|
||||
<gd:fullName>Davy Randall Jones</gd:fullName>
|
||||
<gd:givenName>Davy Randall</gd:givenName>
|
||||
<gd:familyName>Jones</gd:familyName>
|
||||
</gd:name>
|
||||
<gd:email address="davy.jones@example.com" primary="true" rel="http://schemas.google.com/g/2005#other"/>
|
||||
<gContact:website href="http://www.google.com/profiles/109710625881478599011" rel="profile"/>
|
||||
</entry>
|
||||
<entry gd:etag=""Q3w7ezVSLit7I2A9WB5WGUkNRgE."">
|
||||
<id>http://www.google.com/m8/feeds/contacts/tester%40mochi.com/base/3</id>
|
||||
<updated>2007-08-01T05:45:52.203Z</updated>
|
||||
<app:edited xmlns:app="http://www.w3.org/2007/app">2007-08-01T05:45:52.203Z</app:edited>
|
||||
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
|
||||
<title/>
|
||||
<link href="https://www.google.com/m8/feeds/photos/media/tester%40mochi.com/3" rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full/3" rel="self" type="application/atom+xml"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full/3" rel="edit" type="application/atom+xml"/>
|
||||
<gd:email address="noname@example.com" primary="true" rel="http://schemas.google.com/g/2005#other"/>
|
||||
</entry>
|
||||
<entry gd:etag=""Q3w7ezVSLit7I2A9WB5WGUkNRgE."">
|
||||
<id>http://www.google.com/m8/feeds/contacts/tester%40mochi.com/base/7</id>
|
||||
<updated>2007-08-01T05:45:52.203Z</updated>
|
||||
<app:edited xmlns:app="http://www.w3.org/2007/app">2007-08-01T05:45:52.203Z</app:edited>
|
||||
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
|
||||
<title/>
|
||||
<link href="https://www.google.com/m8/feeds/photos/media/tester%40mochi.com/7" rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full/7" rel="self" type="application/atom+xml"/>
|
||||
<link href="https://www.google.com/m8/feeds/contacts/tester%40mochi.com/full/7" rel="edit" type="application/atom+xml"/>
|
||||
<gd:email address="lycnix" primary="true" rel="http://schemas.google.com/g/2005#other"/>
|
||||
</entry>
|
||||
</feed>
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"access_token": "test-token"
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, Constructor: CC} = Components;
|
||||
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
|
||||
"nsIBinaryInputStream",
|
||||
"setInputStream");
|
||||
|
||||
function handleRequest(req, res) {
|
||||
try {
|
||||
reallyHandleRequest(req, res);
|
||||
} catch (ex) {
|
||||
res.setStatusLine("1.0", 200, "AlmostOK");
|
||||
let msg = "Error handling request: " + ex + "\n" + ex.stack;
|
||||
log(msg);
|
||||
res.write(msg);
|
||||
}
|
||||
}
|
||||
|
||||
function log(msg) {
|
||||
// dump("GOOGLE-SERVER-MOCK: " + msg + "\n");
|
||||
}
|
||||
|
||||
const kBasePath = "browser/browser/components/loop/test/mochitest/fixtures/";
|
||||
|
||||
const kStatusCodes = {
|
||||
400: "Bad Request",
|
||||
401: "Unauthorized",
|
||||
403: "Forbidden",
|
||||
404: "Not Found",
|
||||
405: "Method Not Allowed",
|
||||
500: "Internal Server Error",
|
||||
501: "Not Implemented",
|
||||
503: "Service Unavailable"
|
||||
};
|
||||
|
||||
function HTTPError(code = 500, message) {
|
||||
this.code = code;
|
||||
this.name = kStatusCodes[code] || "HTTPError";
|
||||
this.message = message || this.name;
|
||||
}
|
||||
HTTPError.prototype = new Error();
|
||||
HTTPError.prototype.constructor = HTTPError;
|
||||
|
||||
function sendError(res, err) {
|
||||
if (!(err instanceof HTTPError)) {
|
||||
err = new HTTPError(typeof err == "number" ? err : 500,
|
||||
err.message || typeof err == "string" ? err : "");
|
||||
}
|
||||
res.setStatusLine("1.1", err.code, err.name);
|
||||
res.write(err.message);
|
||||
}
|
||||
|
||||
function parseQuery(query, params = {}) {
|
||||
for (let param of query.replace(/^[?&]/, "").split(/(?:&|\?)/)) {
|
||||
param = param.split("=");
|
||||
if (!param[0])
|
||||
continue;
|
||||
params[unescape(param[0])] = unescape(param[1]);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
function getRequestBody(req) {
|
||||
let avail;
|
||||
let bytes = [];
|
||||
let body = new BinaryInputStream(req.bodyInputStream);
|
||||
|
||||
while ((avail = body.available()) > 0)
|
||||
Array.prototype.push.apply(bytes, body.readByteArray(avail));
|
||||
|
||||
return String.fromCharCode.apply(null, bytes);
|
||||
}
|
||||
|
||||
function getInputStream(path) {
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties)
|
||||
.get("CurWorkD", Ci.nsILocalFile);
|
||||
for (let part of path.split("/"))
|
||||
file.append(part);
|
||||
let fileStream = Cc["@mozilla.org/network/file-input-stream;1"]
|
||||
.createInstance(Ci.nsIFileInputStream);
|
||||
fileStream.init(file, 1, 0, false);
|
||||
return fileStream;
|
||||
}
|
||||
|
||||
function checkAuth(req) {
|
||||
if (!req.hasHeader("Authorization"))
|
||||
throw new HTTPError(401, "No Authorization header provided.");
|
||||
|
||||
let auth = req.getHeader("Authorization");
|
||||
if (auth != "Bearer test-token")
|
||||
throw new HTTPError(401, "Invalid Authorization header content: '" + auth + "'");
|
||||
}
|
||||
|
||||
function reallyHandleRequest(req, res) {
|
||||
log("method: " + req.method);
|
||||
|
||||
let body = getRequestBody(req);
|
||||
log("body: " + body);
|
||||
|
||||
let contentType = req.hasHeader("Content-Type") ? req.getHeader("Content-Type") : null;
|
||||
log("contentType: " + contentType);
|
||||
|
||||
let params = parseQuery(req.queryString);
|
||||
parseQuery(body, params);
|
||||
log("params: " + JSON.stringify(params));
|
||||
|
||||
// Delegate an authentication request to the correct handler.
|
||||
if ("action" in params) {
|
||||
methodHandlers[params.action](req, res, params);
|
||||
} else {
|
||||
sendError(res, 501);
|
||||
}
|
||||
}
|
||||
|
||||
function respondWithFile(res, fileName, mimeType) {
|
||||
res.setStatusLine("1.1", 200, "OK");
|
||||
res.setHeader("Content-Type", mimeType);
|
||||
|
||||
let inputStream = getInputStream(kBasePath + fileName);
|
||||
res.bodyOutputStream.writeFrom(inputStream, inputStream.available());
|
||||
inputStream.close();
|
||||
}
|
||||
|
||||
const methodHandlers = {
|
||||
auth: function(req, res, params) {
|
||||
respondWithFile(res, "google_auth.txt", "text/html");
|
||||
},
|
||||
|
||||
token: function(req, res, params) {
|
||||
respondWithFile(res, "google_token.txt", "application/json");
|
||||
},
|
||||
|
||||
contacts: function(req, res, params) {
|
||||
try {
|
||||
checkAuth(req);
|
||||
} catch (ex) {
|
||||
sendError(res, ex, ex.code);
|
||||
return;
|
||||
}
|
||||
|
||||
respondWithFile(res, "google_contacts.txt", "text/xml");
|
||||
}
|
||||
};
|
|
@ -198,3 +198,51 @@ let mockPushHandler = {
|
|||
this._notificationCallback(version);
|
||||
}
|
||||
};
|
||||
|
||||
const mockDb = {
|
||||
_store: { },
|
||||
_next_guid: 1,
|
||||
|
||||
add: function(details, callback) {
|
||||
if (!("id" in details)) {
|
||||
callback(new Error("No 'id' field present"));
|
||||
return;
|
||||
}
|
||||
details._guid = this._next_guid++;
|
||||
this._store[details._guid] = details;
|
||||
callback(null, details);
|
||||
},
|
||||
remove: function(guid, callback) {
|
||||
if (!guid in this._store) {
|
||||
callback(new Error("Could not find _guid '" + guid + "' in database"));
|
||||
return;
|
||||
}
|
||||
delete this._store[guid];
|
||||
callback(null);
|
||||
},
|
||||
getAll: function(callback) {
|
||||
callback(null, this._store);
|
||||
},
|
||||
get: function(guid, callback) {
|
||||
callback(null, this._store[guid]);
|
||||
},
|
||||
getByServiceId: function(serviceId, callback) {
|
||||
for (let guid in this._store) {
|
||||
if (serviceId === this._store[guid].id) {
|
||||
callback(null, this._store[guid]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback(null, null);
|
||||
},
|
||||
removeAll: function(callback) {
|
||||
this._store = {};
|
||||
this._next_guid = 1;
|
||||
callback(null);
|
||||
},
|
||||
promise: function(method, ...params) {
|
||||
return new Promise(resolve => {
|
||||
this[method](...params, (err, res) => err ? reject(err) : resolve(res));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -249,6 +249,8 @@ user_pref("browser.newtabpage.directory.ping", "");
|
|||
// Enable Loop
|
||||
user_pref("loop.enabled", true);
|
||||
user_pref("loop.throttled", false);
|
||||
user_pref("loop.oauth.google.URL", "http://%(server)s/browser/browser/components/loop/test/mochitest/google_service.sjs?action=");
|
||||
user_pref("loop.oauth.google.getContactsURL", "http://%(server)s/browser/browser/components/loop/test/mochitest/google_service.sjs?action=contacts");
|
||||
|
||||
// Ensure UITour won't hit the network
|
||||
user_pref("browser.uitour.pinnedTabUrl", "http://%(server)s/uitour-dummy/pinnedTab");
|
||||
|
|
Загрузка…
Ссылка в новой задаче