Merge mozilla-central to autoland

This commit is contained in:
Dorel Luca 2018-04-03 01:12:17 +03:00
Родитель 0e79fd0b72 a7d5a65268
Коммит 465b8a1f5d
52 изменённых файлов: 1111 добавлений и 798 удалений

Просмотреть файл

@ -477,6 +477,7 @@
"SearchBar": {
"description": "Sets the default location of the search bar. Only applies on firtrun, but can be changed.",
"first_available": "60.0",
"enterprise_only": true,
"type": "string",
"enum": ["unified", "separate"]

Просмотреть файл

@ -10,6 +10,9 @@ ac_add_options --enable-optimize
ac_add_options --enable-clang-plugin
. $topsrcdir/build/win32/mozconfig.vs-latest
# Regardless of what mozconfig.vs-latest sets, clang-plugin builds need to use
# the Microsoft linker until at least bugs 1414287 and 1427808 are resolved.
export LINKER=link
. "$topsrcdir/build/mozconfig.common.override"
. "$topsrcdir/build/mozconfig.clang-cl"

Просмотреть файл

@ -11,6 +11,9 @@ ac_add_options --enable-debug
ac_add_options --enable-clang-plugin
. $topsrcdir/build/win32/mozconfig.vs-latest
# Regardless of what mozconfig.vs-latest sets, clang-plugin builds need to use
# the Microsoft linker until at least bugs 1414287 and 1427808 are resolved.
export LINKER=link
. "$topsrcdir/build/mozconfig.common.override"
. "$topsrcdir/build/mozconfig.clang-cl"

Просмотреть файл

@ -11,6 +11,9 @@ ac_add_options --enable-dmd
ac_add_options --enable-clang-plugin
. $topsrcdir/build/win32/mozconfig.vs-latest
# Regardless of what mozconfig.vs-latest sets, clang-plugin builds need to use
# the Microsoft linker until at least bugs 1414287 and 1427808 are resolved.
export LINKER=link
. "$topsrcdir/build/mozconfig.common.override"
. "$topsrcdir/build/mozconfig.clang-cl"

Просмотреть файл

@ -10,6 +10,9 @@ ac_add_options --enable-optimize
ac_add_options --enable-clang-plugin
. $topsrcdir/build/win64/mozconfig.vs-latest
# Regardless of what mozconfig.vs-latest sets, clang-plugin builds need to use
# the Microsoft linker until at least bugs 1414287 and 1427808 are resolved.
export LINKER=link
. "$topsrcdir/build/mozconfig.common.override"
. "$topsrcdir/build/mozconfig.clang-cl"

Просмотреть файл

@ -11,6 +11,9 @@ ac_add_options --enable-debug
ac_add_options --enable-clang-plugin
. $topsrcdir/build/win64/mozconfig.vs-latest
# Regardless of what mozconfig.vs-latest sets, clang-plugin builds need to use
# the Microsoft linker until at least bugs 1414287 and 1427808 are resolved.
export LINKER=link
. "$topsrcdir/build/mozconfig.common.override"
. "$topsrcdir/build/mozconfig.clang-cl"

Просмотреть файл

@ -13,6 +13,9 @@ ac_add_options --enable-clang-plugin
ac_add_options --enable-mozsearch-plugin
. $topsrcdir/build/win64/mozconfig.vs-latest
# Regardless of what mozconfig.vs-latest sets, clang-plugin builds need to use
# the Microsoft linker until at least bugs 1414287 and 1427808 are resolved.
export LINKER=link
. "$topsrcdir/build/mozconfig.common.override"
. "$topsrcdir/build/mozconfig.clang-cl"

Просмотреть файл

@ -11,10 +11,10 @@ updater.app/Contents/MacOS/org.mozilla.updater
updater.app/Contents/PkgInfo
browser/chrome.manifest
# browser branding / themes is bug 1313106
browser/chrome/browser/content/branding/icon128.png
browser/chrome/browser/content/branding/icon16.png
browser/chrome/browser/content/branding/icon32.png
browser/chrome/browser/content/branding/icon48.png
browser/chrome/browser/content/branding/icon64.png
browser/chrome/browser/content/browser/defaultthemes/5.header.png
browser/chrome/browser/content/browser/extension.svg
browser/chrome/browser/content/browser/places/bookmarkProperties.xul
@ -145,5 +145,5 @@ res/table-remove-row.gif
res/multilocale.txt
update.locale
# Aurora branding
browser/chrome/browser/content/branding/icon64.png
browser/chrome/browser/content/branding/icon128.png
browser/chrome/devtools/content/framework/dev-edition-promo/dev-edition-logo.png

Двоичные данные
browser/themes/linux/social/services-16.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 839 B

Двоичные данные
browser/themes/linux/social/services-64.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 5.5 KiB

Двоичные данные
browser/themes/osx/social/services-16.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 839 B

Двоичные данные
browser/themes/osx/social/services-16@2x.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.1 KiB

Двоичные данные
browser/themes/osx/social/services-64.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 5.5 KiB

Двоичные данные
browser/themes/osx/social/services-64@2x.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 14 KiB

Двоичные данные
browser/themes/windows/social/services-16.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 839 B

Двоичные данные
browser/themes/windows/social/services-64.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 5.5 KiB

Просмотреть файл

@ -1,5 +1,5 @@
{
"llvm_revision": "326909",
"llvm_revision": "328769",
"stages": "3",
"build_libcxx": false,
"build_type": "Release",

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 6.6 KiB

После

Ширина:  |  Высота:  |  Размер: 14 KiB

Просмотреть файл

@ -391,17 +391,6 @@ PaymentRequest::IsValidCurrencyAmount(const nsAString& aItem,
nsAString& aErrorMsg)
{
nsresult rv;
if (aIsTotalItem) {
rv = IsNonNegativeNumber(aItem, aAmount.mValue, aErrorMsg);
if (NS_FAILED(rv)) {
return rv;
}
} else {
rv = IsValidNumber(aItem, aAmount.mValue, aErrorMsg);
if (NS_FAILED(rv)) {
return rv;
}
}
// currencySystem must equal urn:iso:std:iso:4217
if (!aAmount.mCurrencySystem.EqualsASCII("urn:iso:std:iso:4217")) {
aErrorMsg.AssignLiteral("The amount.currencySystem of \"");
@ -415,6 +404,17 @@ PaymentRequest::IsValidCurrencyAmount(const nsAString& aItem,
if (NS_FAILED(rv)) {
return rv;
}
if (aIsTotalItem) {
rv = IsNonNegativeNumber(aItem, aAmount.mValue, aErrorMsg);
if (NS_FAILED(rv)) {
return rv;
}
} else {
rv = IsValidNumber(aItem, aAmount.mValue, aErrorMsg);
if (NS_FAILED(rv)) {
return rv;
}
}
return NS_OK;
}
@ -681,7 +681,8 @@ PaymentRequest::RespondCanMakePayment(bool aResult)
}
already_AddRefed<Promise>
PaymentRequest::Show(ErrorResult& aRv)
PaymentRequest::Show(const Optional<OwningNonNull<Promise>>& aDetailsPromise,
ErrorResult& aRv)
{
if (mState != eCreated) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
@ -708,6 +709,12 @@ PaymentRequest::Show(ErrorResult& aRv)
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
if (aDetailsPromise.WasPassed()) {
aDetailsPromise.Value().AppendNativeHandler(this);
mUpdating = true;
}
nsresult rv = manager->ShowPayment(mInternalId);
if (NS_WARN_IF(NS_FAILED(rv))) {
if (rv == NS_ERROR_ABORT) {
@ -999,6 +1006,43 @@ PaymentRequest::GetShippingType() const
return mShippingType;
}
void
PaymentRequest::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
{
MOZ_ASSERT(aCx);
mUpdating = false;
if (NS_WARN_IF(!aValue.isObject())) {
return;
}
// Converting value to a PaymentDetailsUpdate dictionary
PaymentDetailsUpdate details;
if (!details.Init(aCx, aValue)) {
AbortUpdate(NS_ERROR_DOM_TYPE_ERR);
JS_ClearPendingException(aCx);
return;
}
nsresult rv = IsValidDetailsUpdate(details, mRequestShipping);
if (NS_FAILED(rv)) {
AbortUpdate(rv);
return;
}
// Update the PaymentRequest with the new details
if (NS_FAILED(UpdatePayment(aCx, details))) {
AbortUpdate(NS_ERROR_DOM_ABORT_ERR);
return;
}
}
void
PaymentRequest::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
{
mUpdating = false;
AbortUpdate(NS_ERROR_DOM_ABORT_ERR);
}
PaymentRequest::~PaymentRequest()
{
}

Просмотреть файл

@ -10,6 +10,7 @@
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/PaymentRequestBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/ErrorResult.h"
#include "nsWrapperCache.h"
#include "PaymentRequestUpdateEvent.h"
@ -22,6 +23,7 @@ class PaymentAddress;
class PaymentResponse;
class PaymentRequest final : public DOMEventTargetHelper
, public PromiseNativeHandler
{
public:
NS_DECL_ISUPPORTS_INHERITED
@ -90,7 +92,8 @@ public:
already_AddRefed<Promise> CanMakePayment(ErrorResult& aRv);
void RespondCanMakePayment(bool aResult);
already_AddRefed<Promise> Show(ErrorResult& aRv);
already_AddRefed<Promise> Show(const Optional<OwningNonNull<Promise>>& detailsPromise,
ErrorResult& aRv);
void RespondShowPayment(const nsAString& aMethodName,
const nsAString& aDetails,
const nsAString& aPayerName,
@ -110,6 +113,7 @@ public:
bool Equals(const nsAString& aInternalId) const;
bool ReadyForUpdate();
bool IsUpdating() const { return mUpdating; }
void SetUpdating(bool aUpdating);
already_AddRefed<PaymentAddress> GetShippingAddress() const;
@ -142,6 +146,11 @@ public:
mRequestShipping = true;
}
void
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
void
RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
IMPL_EVENT_HANDLER(shippingaddresschange);
IMPL_EVENT_HANDLER(shippingoptionchange);

Просмотреть файл

@ -374,7 +374,7 @@ PaymentRequestManager::GetPaymentRequestById(const nsAString& aRequestId)
}
void
GetSelectedShippingOption(const PaymentDetailsInit& aDetails,
GetSelectedShippingOption(const PaymentDetailsBase& aDetails,
nsAString& aOption)
{
SetDOMStringToNull(aOption);
@ -502,10 +502,12 @@ PaymentRequestManager::ShowPayment(const nsAString& aRequestId)
if (!request) {
return NS_ERROR_FAILURE;
}
nsAutoString requestId(aRequestId);
IPCPaymentShowActionRequest action(requestId);
nsresult rv = SendRequestPayment(request, action);
nsresult rv = NS_OK;
if (!request->IsUpdating()) {
nsAutoString requestId(aRequestId);
IPCPaymentShowActionRequest action(requestId);
rv = SendRequestPayment(request, action);
}
mShowingRequest = request;
return rv;
}
@ -557,19 +559,19 @@ PaymentRequestManager::UpdatePayment(JSContext* aCx,
if (!request) {
return NS_ERROR_UNEXPECTED;
}
// [TODO] Process details.shippingOptions if presented.
// 1) Check if there are duplicate IDs in details.shippingOptions,
// if so, reset details.shippingOptions to an empty sequence.
// 2) Set request's selectedShippingOption to the ID of last selected
// option.
IPCPaymentDetails details;
nsresult rv = ConvertDetailsUpdate(aCx, aDetails, details, aRequestShipping);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsAutoString shippingOption;
SetDOMStringToNull(shippingOption);
if (aRequestShipping) {
GetSelectedShippingOption(aDetails, shippingOption);
request->SetShippingOption(shippingOption);
}
nsAutoString requestId(aRequestId);
IPCPaymentUpdateActionRequest action(requestId, details);
return SendRequestPayment(request, action);
@ -643,12 +645,12 @@ PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse)
request->RespondAbortPayment(response.isSucceeded());
if (response.isSucceeded()) {
MOZ_ASSERT(mShowingRequest == request);
mShowingRequest = nullptr;
mRequestQueue.RemoveElement(request);
nsresult rv = ReleasePaymentChild(request);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
mShowingRequest = nullptr;
nsresult rv = ReleasePaymentChild(request);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
break;
}

Просмотреть файл

@ -368,7 +368,13 @@ PaymentRequestService::RequestPayment(nsIPaymentActionRequest* aRequest)
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = LaunchUIAction(requestId, type);
if (mShowingRequest) {
MOZ_ASSERT(mShowingRequest == payment);
rv = LaunchUIAction(requestId, type);
} else {
mShowingRequest = payment;
rv = LaunchUIAction(requestId, nsIPaymentActionRequest::SHOW_ACTION);
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
@ -420,8 +426,8 @@ PaymentRequestService::RespondPayment(nsIPaymentActionResponse* aResponse)
bool isSucceeded;
rv = response->IsSucceeded(&isSucceeded);
NS_ENSURE_SUCCESS(rv, rv);
mShowingRequest = nullptr;
if (isSucceeded) {
mShowingRequest = nullptr;
mRequestQueue.RemoveElement(request);
}
break;

Просмотреть файл

@ -64,6 +64,8 @@ PaymentRequestUpdateEvent::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value
// Converting value to a PaymentDetailsUpdate dictionary
PaymentDetailsUpdate details;
if (!details.Init(aCx, aValue)) {
mRequest->AbortUpdate(NS_ERROR_TYPE_ERR);
JS_ClearPendingException(aCx);
return;
}

Просмотреть файл

@ -6,7 +6,9 @@
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const paymentSrv = Cc["@mozilla.org/dom/payments/payment-request-service;1"].getService(Ci.nsIPaymentRequestService);
let expectedCompleteStatus;
let expectedCompleteStatus = null;
let expectedShowAction = "accept";
let expectedUpdateAction = "accept";
function emitTestFail(message) {
sendAsyncMessage("test-fail", message);
@ -33,212 +35,127 @@ shippingAddress.init("USA", // country
"Bill A. Pacheco", // recipient
"+1-434-441-3879"); // phone
const DummyUIService = {
showPayment: function(requestId) {
const showResponseData = Cc["@mozilla.org/dom/payments/general-response-data;1"].
createInstance(Ci.nsIGeneralResponseData);
try {
showResponseData.initData({ paymentToken: "6880281f-0df3-4b8e-916f-66575e2457c1",});
} catch (e) {
emitTestFail("Fail to initialize response data with { paymentToken: \"6880281f-0df3-4b8e-916f-66575e2457c1\",}");
}
let showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
createInstance(Ci.nsIPaymentShowActionResponse);
showResponse.init(requestId,
Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED,
"testing-payment-method", // payment method
showResponseData, // payment method data
"Bill A. Pacheco", // payer name
"", // payer email
""); // payer phone
paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
},
abortPayment: function(requestId) {
},
completePayment: function(requestId) {
let payRequest = paymentSrv.getPaymentRequestById(requestId);
if (payRequest.completeStatus == expectedCompleteStatus) {
emitTestPass("request.completeStatus matches expectation of " + expectedCompleteStatus);
} else {
emitTestFail("request.completeStatus incorrect. Expected " +
expectedCompleteStatus + ", got " + payRequest.completeStatus);
}
function acceptShow(requestId) {
const responseData = Cc["@mozilla.org/dom/payments/general-response-data;1"].
createInstance(Ci.nsIGeneralResponseData);
responseData.initData({ paymentToken: "6880281f-0df3-4b8e-916f-66575e2457c1",});
let showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
createInstance(Ci.nsIPaymentShowActionResponse);
showResponse.init(requestId,
Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED,
"testing-payment-method", // payment method
responseData, // payment method data
"Bill A. Pacheco", // payer name
"", // payer email
""); // payer phone
paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
}
let completeResponse = Cc["@mozilla.org/dom/payments/payment-complete-action-response;1"].
createInstance(Ci.nsIPaymentCompleteActionResponse);
completeResponse.init(requestId, Ci.nsIPaymentActionResponse.COMPLETE_SUCCEEDED);
paymentSrv.respondPayment(completeResponse.QueryInterface(Ci.nsIPaymentActionResponse));
},
updatePayment: function(requestId) {
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIService]),
};
const NormalUIService = {
shippingOptionChanged: false,
showPayment: function(requestId) {
paymentSrv.changeShippingAddress(requestId, shippingAddress);
},
abortPayment: function(requestId) {
},
completePayment: function(requestId) {
let payRequest = paymentSrv.getPaymentRequestById(requestId);
if (payRequest.completeStatus == expectedCompleteStatus) {
emitTestPass("request.completeStatus matches expectation of " + expectedCompleteStatus);
} else {
emitTestFail("request.completeStatus incorrect. Expected " +
expectedCompleteStatus + ", got " + payRequest.completeStatus);
}
let completeResponse = Cc["@mozilla.org/dom/payments/payment-complete-action-response;1"].
createInstance(Ci.nsIPaymentCompleteActionResponse);
completeResponse.init(requestId, Ci.nsIPaymentActionResponse.COMPLETE_SUCCEEDED);
paymentSrv.respondPayment(completeResponse.QueryInterface(Ci.nsIPaymentActionResponse));
},
updatePayment: function(requestId) {
let showResponse = null;
let payRequest = paymentSrv.getPaymentRequestById(requestId);
if (payRequest.paymentDetails.error != "") {
emitTestFail("updatedDetails should not have errors(" + payRequest.paymentDetails.error + ").");
}
if (!this.shippingOptionChanged) {
paymentSrv.changeShippingOption(requestId, "FastShipping");
this.shippingOptionChanged = true;
} else {
const shippingOptions = payRequest.paymentDetails.shippingOptions;
let shippingOption = shippingOptions.queryElementAt(0, Ci.nsIPaymentShippingOption);
if (shippingOption.selected) {
emitTestFail(shippingOption.label + " should not be selected.");
}
shippingOption = shippingOptions.queryElementAt(1, Ci.nsIPaymentShippingOption);
if (!shippingOption.selected) {
emitTestFail(shippingOption.label + " should be selected.");
}
const showResponseData = Cc["@mozilla.org/dom/payments/general-response-data;1"].
createInstance(Ci.nsIGeneralResponseData);
try {
showResponseData.initData({ paymentToken: "6880281f-0df3-4b8e-916f-66575e2457c1",});
} catch (e) {
emitTestFail("Fail to initialize response data with { paymentToken: \"6880281f-0df3-4b8e-916f-66575e2457c1\",}");
}
showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
createInstance(Ci.nsIPaymentShowActionResponse);
showResponse.init(requestId,
Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED,
"testing-payment-method", // payment method
showResponseData, // payment method data
"Bill A. Pacheco", // payer name
"", // payer email
""); // payer phone
paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
}
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIService]),
};
const RejectUIService = {
showPayment: function(requestId) {
const responseData = Cc["@mozilla.org/dom/payments/general-response-data;1"].
createInstance(Ci.nsIGeneralResponseData);
try {
responseData.initData({});
} catch (e) {
emitTestFail("Fail to initialize response data with empty object.");
}
const showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
createInstance(Ci.nsIPaymentShowActionResponse);
showResponse.init(requestId,
Ci.nsIPaymentActionResponse.PAYMENT_REJECTED,
"", // payment method
responseData, // payment method data
"", // payer name
"", // payer email
""); // payer phone
paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
},
abortPayment: function(requestId) {
},
completePayment: function(requestId) {
},
updatePayment: function(requestId) {
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIService]),
};
const ErrorUIService = {
showPayment: function(requestId) {
paymentSrv.changeShippingOption(requestId, "");
},
abortPayment: function(requestId) {
},
completePayment: function(requestId) {
},
updatePayment: function(requestId) {
let payRequest = paymentSrv.getPaymentRequestById(requestId);
if (!payRequest) {
emitTestFail("Fail to get existing payment request.");
}
if (payRequest.paymentDetails.error != "Update with Error") {
emitTestFail("details.error should be 'Update with Error', but got " + payRequest.paymentDetails.error + ".");
}
const responseData = Cc["@mozilla.org/dom/payments/general-response-data;1"].
createInstance(Ci.nsIGeneralResponseData);
try {
responseData.initData({});
} catch (e) {
emitTestFail("Fail to initialize response data with empty object.");
}
const showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
createInstance(Ci.nsIPaymentShowActionResponse);
showResponse.init(requestId,
Ci.nsIPaymentActionResponse.PAYMENT_REJECTED,
"", // payment method
responseData, // payment method data
"", // payer name
"", // payer email
""); // payer phone
paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIService]),
};
const CompleteUIService = {
showPayment: function(requestId) {
const showResponseData = Cc["@mozilla.org/dom/payments/general-response-data;1"].
createInstance(Ci.nsIGeneralResponseData);
try {
showResponseData.initData({});
} catch (e) {
emitTestFail("Fail to initialize response data with empty object.");
}
let showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
function rejectShow(requestId) {
const responseData = Cc["@mozilla.org/dom/payments/general-response-data;1"].
createInstance(Ci.nsIGeneralResponseData);
responseData.initData({});
const showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
createInstance(Ci.nsIPaymentShowActionResponse);
showResponse.init(requestId,
Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED,
"", // payment method
showResponseData, // payment method data
"", // payer name
"", // payer email
""); // payer phone
paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
},
abortPayment: function(requestId) {
},
completePayment: function(requestId) {
},
updatePayment: function(requestId) {
},
showResponse.init(requestId,
Ci.nsIPaymentActionResponse.PAYMENT_REJECTED,
"", // payment method
responseData, // payment method data
"", // payer name
"", // payer email
""); // payer phone
paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
}
function updateShow(requestId) {
if (expectedUpdateAction == "updateaddress") {
paymentSrv.changeShippingAddress(requestId, shippingAddress);
} else if (expectedUpdateAction == "accept" || expectedUpdateAction == "error"){
paymentSrv.changeShippingOption(requestId, "FastShipping");
} else {
emitTestFail("Unknown expected update action: " + expectedUpdateAction);
}
}
function showRequest(requestId) {
if (expectedShowAction == "accept") {
acceptShow(requestId);
} else if (expectedShowAction == "reject") {
rejectShow(requestId);
} else if (expectedShowAction == "update") {
updateShow(requestId);
} else {
emitTestFail("Unknown expected show action: " + expectedShowAction);
}
}
function abortRequest(requestId) {
let abortResponse = Cc["@mozilla.org/dom/payments/payment-abort-action-response;1"].
createInstance(Ci.nsIPaymentAbortActionResponse);
abortResponse.init(requestId, Ci.nsIPaymentActionResponse.ABORT_SUCCEEDED);
paymentSrv.respondPayment(abortResponse);
}
function completeRequest(requestId) {
let payRequest = paymentSrv.getPaymentRequestById(requestId);
if (expectedCompleteStatus) {
if (payRequest.completeStatus == expectedCompleteStatus) {
emitTestPass("request.completeStatus matches expectation of " +
expectedCompleteStatus);
} else {
emitTestFail("request.completeStatus incorrect. Expected " +
expectedCompleteStatus + ", got " + payRequest.completeStatus);
}
}
let completeResponse = Cc["@mozilla.org/dom/payments/payment-complete-action-response;1"].
createInstance(Ci.nsIPaymentCompleteActionResponse);
completeResponse.init(requestId, Ci.nsIPaymentActionResponse.COMPLETE_SUCCEEDED);
paymentSrv.respondPayment(completeResponse.QueryInterface(Ci.nsIPaymentActionResponse));
}
function updateRequest(requestId) {
let request = paymentSrv.getPaymentRequestById(requestId);
if (expectedUpdateAction == "accept") {
if (request.paymentDetails.error != "") {
emitTestFail("updatedDetails should not have errors(" + request.paymentDetails.error + ").");
}
const shippingOptions = request.paymentDetails.shippingOptions;
let shippingOption = shippingOptions.queryElementAt(0, Ci.nsIPaymentShippingOption);
if (shippingOption.selected) {
emitTestFail(shippingOption.label + " should not be selected.");
}
shippingOption = shippingOptions.queryElementAt(1, Ci.nsIPaymentShippingOption);
if (!shippingOption.selected) {
emitTestFail(shippingOption.label + " should be selected.");
}
acceptShow(requestId);
} else if (expectedUpdateAction == "error") {
if (request.paymentDetails.error != "Update with Error") {
emitTestFail("details.error should be 'Update with Error', but got " + request.paymentDetails.error + ".");
}
rejectShow(requestId);
} else if (expectedUpdateAction == "updateaddress") {
if (request.paymentDetails.error != "") {
emitTestFail("updatedDetails should not have errors(" + request.paymentDetails.error + ").");
}
expectedUpdateAction = "accept";
paymentSrv.changeShippingOption(requestId, "FastShipping");
} else {
emitTestFail("Unknown expected update aciton: " + expectedUpdateAction);
}
}
const DummyUIService = {
showPayment: showRequest,
abortPayment: abortRequest,
completePayment: completeRequest,
updatePayment: updateRequest,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIService]),
};
function testInitDataAndResponse() {
paymentSrv.setTestingUIService(DummyUIService.QueryInterface(Ci.nsIPaymentUIService));
function testShowResponseInit() {
const showResponseData = Cc["@mozilla.org/dom/payments/general-response-data;1"].
createInstance(Ci.nsIGeneralResponseData);
try {
@ -248,6 +165,7 @@ function testInitDataAndResponse() {
if (e.name != "NS_ERROR_FAILURE") {
emitTestFail("Expected 'NS_ERROR_FAILURE' when initializing nsIGeneralResponseData with null object, but got " + e.name + ".");
}
emitTestPass("Get expected result for initializing nsIGeneralResponseData with null object");
}
const showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
createInstance(Ci.nsIPaymentShowActionResponse);
@ -259,6 +177,7 @@ function testInitDataAndResponse() {
"Bill A. Pacheco", // payer name
"", // payer email
""); // payer phone
emitTestPass("Get expected result for initializing response with accepted and empty data.");
} catch (e) {
emitTestFail("Unexpected error " + e.name + " when initializing response with accepted and empty data.");
}
@ -271,6 +190,7 @@ function testInitDataAndResponse() {
"Bill A. Pacheco",
"",
"");
emitTestPass("Get expected result for initializing response with rejected and null data.");
} catch (e) {
emitTestFail("Unexpected error " + e.name + " when initializing response with rejected and null data.");
}
@ -288,31 +208,42 @@ function testInitDataAndResponse() {
if (e.name != "NS_ERROR_ILLEGAL_VALUE") {
emitTestFail("Expected 'NS_ERROR_ILLEGAL_VALUE', but got " + e.name + ".");
}
emitTestPass("Get expected result for initializing response with accepted and null data.")
}
sendAsyncMessage("test-init-data-and-response-complete");
sendAsyncMessage("test-show-response-init-complete");
}
addMessageListener("set-dummy-ui-service", function() {
paymentSrv.setTestingUIService(DummyUIService.QueryInterface(Ci.nsIPaymentUIService));
addMessageListener("set-simple-ui-service", function() {
expectedCompleteStatus = null;
expectedShowAction = "accept";
expectedUpdateAction = "accept";
});
addMessageListener("set-normal-ui-service", function() {
paymentSrv.setTestingUIService(NormalUIService.QueryInterface(Ci.nsIPaymentUIService));
expectedCompleteStatus = null;
expectedShowAction = "update";
expectedUpdateAction = "updateaddress";
});
addMessageListener("set-reject-ui-service", function() {
paymentSrv.setTestingUIService(RejectUIService.QueryInterface(Ci.nsIPaymentUIService));
expectedCompleteStatus = null;
expectedShowAction = "reject";
expectedUpdateAction = "accept";
});
addMessageListener("set-update-with-ui-service", function() {
expectedCompleteStatus = null;
expectedShowAction = "update";
expectedUpdateAction = "accept";
});
addMessageListener("set-update-with-error-ui-service", function() {
paymentSrv.setTestingUIService(ErrorUIService.QueryInterface(Ci.nsIPaymentUIService));
expectedCompleteStatus = null;
expectedShowAction = "update";
expectedUpdateAction = "error";
});
addMessageListener("set-complete-ui-service", function() {
paymentSrv.setTestingUIService(CompleteUIService.QueryInterface(Ci.nsIPaymentUIService));
});
addMessageListener("test-init-data-and-response", testInitDataAndResponse);
addMessageListener("test-show-response-init", testShowResponseInit);
addMessageListener("set-complete-status-success", function() {
expectedCompleteStatus = "success";

Просмотреть файл

@ -25,6 +25,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345366
gScript.addMessageListener("test-fail", testFailHandler);
gScript.addMessageListener("test-pass", testPassHandler);
// testing data declaration
// default parameters for PaymentRequest construction
const defaultMethods = [{
supportedMethods: "basic-card",
data: {
@ -36,15 +38,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345366
}, {
supportedMethods: "testing-payment-method",
}];
const defaultTotal = {
label: "Total",
amount: {
currency: "USD",
value: "1.00",
},
}
const defaultDetails = {
id: "test payment",
total: {
label: "Total",
amount: {
currency: "USD",
value: "1.00"
}
},
total: defaultTotal,
shippingOptions: [
{
id: "NormalShipping",
@ -75,14 +80,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345366
shippingType: "shipping"
};
const updatedOptionDetails = {
total: {
label: "Total",
amount: {
currency: "USD",
value: "1.00"
}
},
// testing data for PaymentRequestUpdateEvent.updateWith()
const updatedShippingOptionsDetails = {
total: defaultTotal,
shippingOptions: [
{
id: "NormalShipping",
@ -106,180 +106,78 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345366
};
const updatedErrorDetails = {
total: {
label: "Total",
amount: {
currency: "USD",
value: "1.00"
}
},
shippingOptions: [
{
id: "NormalShipping",
label: "NormalShipping",
amount: {
currency: "USD",
value: "10.00"
},
selected: false,
},
{
id: "FastShipping",
label: "FastShipping",
amount: {
currency: "USD",
value: "30.00"
},
selected: false,
},
],
total: defaultTotal,
error: "Update with Error",
};
// Promise function for PaymentRequestUpdateEvent.updateWith()
function updateWithPromise(detailsUpdate) {
return new Promise((resolve, reject) => {
if (detailsUpdate) {
resolve(detailsUpdate);
} else {
reject();
}
});
}
// testing data for PaymentRequest.show() with Non-supported methods
const nonSupportedMethods = [{
supportedMethods: "nonsupported-method",
}];
function updateWithShippingAddress() {
return new Promise((resolve, reject) => {
resolve(defaultDetails);
});
// checking functions
function checkAddress(address, fromEvent) {
is(address.country, "USA", "address.country should be 'USA'.");
is(address.region, "CA", "address.region should be 'CA'.");
is(address.city, "San Bruno", "address.city should be 'San Bruno'.");
is(address.dependentLocality, "Test locality",
"address.dependentLocality should be 'Test locality'.");
is(address.postalCode, "94066", "address.postalCode should be '94066'.");
is(address.sortingCode, "123456", "address.sortingCode should be '123456'.");
if (fromEvent) {
is(address.addressLine.length, 0, "address.addressLine.length should be 0 from event.");
is(address.organization, "", "address.organization should be empty from event.");
is(address.recipient, "", "address.recipient should be empty from event.");
is(address.phone, "", "address.phone should be empty from event.");
} else {
is(address.addressLine.length, 1, "address.addressLine.length should be 1 from promise.");
is(address.addressLine[0], "Easton Ave", "address.addressLine[0] should be 'Easton Ave' from promise.");
is(address.organization, "Testing Org", "address.organization should be 'Testing Org' from promise.");
is(address.recipient, "Bill A. Pacheco", "address.recipient should be 'Bill A. Pacheco' from promise.");
is(address.phone, "+1-434-441-3879", "address.phone should be '+1-434-441-3879' from promise.");
}
}
function updateWithShippingOption() {
return new Promise((resolve, reject) => {
resolve(updatedOptionDetails);
});
function checkResponse(response) {
is(response.requestId, "test payment", "response.requestId should be 'test payment'.");
is(response.methodName, "testing-payment-method", "response.methodName should be 'testing-payment-method'.");
is(response.details.paymentToken, "6880281f-0df3-4b8e-916f-66575e2457c1", "response.details.paymentToken should be '6880281f-0df3-4b8e-916f-66575e2457c1'.");
checkAddress(response.shippingAddress, false/*fromEvent*/);
is(response.shippingOption, "FastShipping", "response.shippingOption should be 'FastShipping'.");
is(response.payerName, "Bill A. Pacheco", "response.payerName should be 'Bill A. Pacheco'.");
ok(!response.payerEmail, "response.payerEmail should be empty");
ok(!response.payerPhone, "response.payerPhone should be empty");
}
function updateWithError() {
return new Promise((resolve, reject) => {
resolve(updatedErrorDetails);
});
}
function testShowWithSuccess() {
info("starting testShowWithSuccess");
// testing functions
function testShowNormalFlow() {
gScript.sendAsyncMessage("set-normal-ui-service");
gScript.sendAsyncMessage("set-complete-status-success");
return new Promise((resolve, reject) => {
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
payRequest.addEventListener("shippingaddresschange", event => {
is(payRequest.shippingAddress.country, "USA", "payRequest.shippingAddress.country should be 'USA' from event.");
is(payRequest.shippingAddress.addressLine.length, 0, "payRequest.shippingAddress.addressLine.length should be 0 from event.");
is(payRequest.shippingAddress.region, "CA", "payRequest.shippingAddress.region should be 'CA' from event.");
is(payRequest.shippingAddress.city, "San Bruno", "payRequest.shippingAddress.city should be 'San Bruno' from event.");
is(payRequest.shippingAddress.dependentLocality, "Test locality", "payRequest.shippingAddress.dependentLocality should be 'Test locality' from event.");
is(payRequest.shippingAddress.postalCode, "94066", "payRequest.shippingAddress.postalCode should be '94066' from event.");
is(payRequest.shippingAddress.sortingCode, "123456", "payRequest.shippingAddress.sortingCode should be '123456' from event.");
is(payRequest.shippingAddress.organization, "", "payRequest.shippingAddress.organization should be empty from event.");
is(payRequest.shippingAddress.recipient, "", "payRequest.shippingAddress.recipient should be empty from event.");
is(payRequest.shippingAddress.phone, "", "payRequest.shippingAddress.phone should be empty from event.");
event.updateWith(updateWithShippingAddress());
checkAddress(payRequest.shippingAddress, true/*fromEvent*/);
event.updateWith(updateWithPromise(defaultDetails));
});
payRequest.addEventListener("shippingoptionchange", event => {
event.updateWith(updateWithShippingOption());
event.updateWith(updateWithPromise(updatedShippingOptionsDetails));
});
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
payRequest.show().then(response => {
is(response.requestId, "test payment", "response.requestId should be 'test payment'.");
is(response.methodName, "testing-payment-method", "response.methodName should be 'testing-payment-method'.");
is(response.details.paymentToken, "6880281f-0df3-4b8e-916f-66575e2457c1", "response.details.paymentToken should be '6880281f-0df3-4b8e-916f-66575e2457c1'.");
is(response.shippingAddress.country, "USA", "response.shippingAddress.country should be 'USA'.");
is(response.shippingAddress.addressLine.length, 1, "response.shippingAddress.addressLine.length should be 1.");
is(response.shippingAddress.addressLine[0], "Easton Ave", "response.shippingAddress.addressLine[0] should be 'Easton Ave'.");
is(response.shippingAddress.region, "CA", "response.shippingAddress.region should be 'CA'.");
is(response.shippingAddress.city, "San Bruno", "response.shippingAddress.city should be 'San Bruno'.");
is(response.shippingAddress.dependentLocality, "Test locality", "response.shippingAddress.dependentLocality should be 'Test locality'.");
is(response.shippingAddress.postalCode, "94066", "response.shippingAddress.postalCode should be '94066'.");
is(response.shippingAddress.sortingCode, "123456", "response.shippingAddress.sortingCode should be '123456'.");
is(response.shippingAddress.organization, "Testing Org", "response.shippingAddress.organization should be 'Testing Org'.");
is(response.shippingAddress.recipient, "Bill A. Pacheco", "response.shippingAddress.recipient should be 'Bill A. Pacheco'.");
is(response.shippingAddress.phone, "+1-434-441-3879", "response.shippingAddress.phone should be '+1-434-441-3879'.");
is(response.shippingOption, "FastShipping", "response.shippingOption should be 'FastShipping'.");
is(response.payerName, "Bill A. Pacheco", "response.payerName should be 'Bill A. Pacheco'.");
ok(!response.payerEmail, "response.payerEmail should be empty");
ok(!response.payerPhone, "response.payerPhone should be empty");
is(payRequest.shippingAddress.country, "USA", "payRequest.shippingAddress.country should be 'USA' from promise.");
is(payRequest.shippingAddress.addressLine.length, 1, "payRequest.shippingAddress.addressLine.length should be 1 from promise.");
is(payRequest.shippingAddress.addressLine[0], "Easton Ave", "payRequest.shippingAddress.addressLine[0] should be 'Easton Ave' from promise.");
is(payRequest.shippingAddress.region, "CA", "payRequest.shippingAddress.region should be 'CA' from promise.");
is(payRequest.shippingAddress.city, "San Bruno", "payRequest.shippingAddress.city should be 'San Bruno' from promise.");
is(payRequest.shippingAddress.dependentLocality, "Test locality", "payRequest.shippingAddress.dependentLocality should be 'Test locality' from promise.");
is(payRequest.shippingAddress.postalCode, "94066", "payRequest.shippingAddress.postalCode should be '94066' from promise.");
is(payRequest.shippingAddress.sortingCode, "123456", "payRequest.shippingAddress.sortingCode should be '123456' from promise.");
is(payRequest.shippingAddress.organization, "Testing Org", "payRequest.shippingAddress.organization should be 'Testing Org' from promise.");
is(payRequest.shippingAddress.recipient, "Bill A. Pacheco", "payRequest.shippingAddress.recipient should be 'Bill A. Pacheco' from promise.");
is(payRequest.shippingAddress.phone, "+1-434-441-3879", "payRequest.shippingAddress.phone should be '+1-434-441-3879' from promise.");
response.complete("success").then(() =>{
resolve();
}).catch(e => {
ok(false, "Unexpected error: " + e.name);
resolve();
});
}).catch( e => {
ok(false, "Unexpected error: " + e.name);
resolve();
}).finally(handler.destruct);
});
}
function testShowWithFail() {
info("starting testShowWithFail");
gScript.sendAsyncMessage("set-dummy-ui-service");
gScript.sendAsyncMessage("set-complete-status-fail");
return new Promise((resolve, reject) => {
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
payRequest.show().then(response => {
response.complete("fail").then(() => {
resolve();
}).catch(e => {
ok(false, "Unexpected error: " + e.name);
resolve();
});
}).catch( e => {
ok(false, "Unexpected error: " + e.name);
resolve();
}).finally(handler.destruct);
});
}
function testShowWithUnknown() {
info("starting testShowWithUnknown");
gScript.sendAsyncMessage("set-dummy-ui-service");
gScript.sendAsyncMessage("set-complete-status-unknown");
return new Promise((resolve, reject) => {
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
payRequest.show().then(response => {
response.complete("unknown").then(() => {
resolve();
}).catch(e => {
ok(false, "Unexpected error: " + e.name);
resolve();
});
}).catch( e => {
ok(false, "Unexpected error: " + e.name);
resolve();
}).finally(handler.destruct);
});
}
function testShowWithEmpty() {
info("starting testShowWithEmpty");
gScript.sendAsyncMessage("set-dummy-ui-service");
gScript.sendAsyncMessage("set-complete-status-unknown");
return new Promise((resolve, reject) => {
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
payRequest.show().then(response => {
response.complete().then(() => {
checkResponse(response, false);
checkAddress(payRequest.shippingAddress, false);
response.complete().then(() =>{
resolve();
}).catch(e => {
ok(false, "Unexpected error: " + e.name);
@ -292,11 +190,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345366
});
}
// testing show with nonsupported methods
function testCannotMakePaymentShow() {
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
gScript.sendAsyncMessage("set-simple-ui-service");
return new Promise((resolve, reject) => {
const payRequest = new PaymentRequest(nonSupportedMethods, defaultDetails);
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
payRequest.canMakePayment().then(result => {
ok(!result, "canMakePayment() should return false, but got " + result + ".");
payRequest.show().then( () => {
@ -310,12 +209,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345366
});
}
// testing show rejected by user
function testRejectShow() {
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
gScript.sendAsyncMessage("set-reject-ui-service");
return new Promise((resolve, reject) => {
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
payRequest.show().then((result) => {
ok(false, "Should be rejected with 'AbortError', but got resolved");
resolve();
@ -329,45 +228,189 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345366
});
}
function testUpdateWithError() {
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
// testing PaymentResponse.complete() with specified result
function testCompleteStatus(result) {
gScript.sendAsyncMessage("set-simple-ui-service");
if (result) {
gScript.sendAsyncMessage("set-complete-status-"+result);
} else {
gScript.sendAsyncMessage("set-complete-status-unknown");
}
return new Promise((resolve, reject) => {
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
payRequest.show().then(response => {
response.complete(result).then(() => {
resolve();
}).catch(e => {
ok(false, "Unexpected error: " + e.name);
resolve();
});
}).catch( e => {
ok(false, "Unexpected error: " + e.name);
resolve();
}).finally(handler.destruct);
});
}
gScript.sendAsyncMessage("set-update-with-error-ui-service");
function testCompleteFail() {
return testCompleteStatus("fail");
}
function testCompleteSuccess() {
return testCompleteStatus("success");
}
function testCompleteUnknown() {
return testCompleteStatus("unknown");
}
function testCompleteEmpty() {
return testCompleteStatus();
}
// testing PaymentRequestUpdateEvent.updateWith with specified details and error
function testUpdateWith(detailsUpdate, expectedError) {
if (expectedError) {
gScript.sendAsyncMessage("set-update-with-error-ui-service");
} else {
gScript.sendAsyncMessage("set-update-with-ui-service");
}
return new Promise((resolve, reject) => {
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
payRequest.addEventListener("shippingaddresschange", event => {
event.updateWith(updateWithError());
event.updateWith(updateWithPromise(detailsUpdate));
});
payRequest.addEventListener("shippingoptionchange", event => {
event.updateWith(updateWithError());
event.updateWith(updateWithPromise(detailsUpdate));
});
payRequest.show().then((result) => {
ok(false, "Should be rejected with 'AbortError', but got resolved");
resolve();
}, (result) => {
is(result.name, "AbortError", "Should be rejected with 'AbortError', but got " + result.name + ".");
resolve();
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
payRequest.show().then(response => {
if (expectedError) {
ok(false, "Should be rejected with " + expectedError + ", but got resolved");
resolve();
} else {
response.complete("success").then(() => {
resolve();
})
}
}, response => {
if (expectedError) {
is(response.name, expectedError,
"Should be rejected with " + expectedError + ", but got " + response.name);
} else {
ok(false, "Unexpected error: " + response.name);
}
resolve();
}).catch(e => {
ok(false, "Unexpected error: " + e.name);
resolve();
resolve();
}).finally(handler.destruct);
});
}
function testNullDetailsResponse() {
function testUpdateWithReject() {
return testUpdateWith(null, "AbortError");
}
function testUpdateWithValidDetails() {
return testUpdateWith(updatedShippingOptionsDetails, null);
}
function testUpdateWithInvalidDetails() {
return testUpdateWith({total: "invalid details"}, "TypeError");
}
function testUpdateWithError() {
return testUpdateWith(updatedErrorDetails, "AbortError");
}
// testing show with detailsUpdate promise
function testShowWithDetailsPromise(detailsUpdate, expectedError) {
if (expectedError) {
gScript.sendAsyncMessage("set-reject-ui-service");
} else {
gScript.sendAsyncMessage("set-simple-ui-service");
}
return new Promise((resolve, reject) => {
gScript.addMessageListener("test-init-data-and-response-complete",
function nullDetailsResponseCompleteHandler() {
gScript.removeMessageListener("test-init-data-and-response-complete",
nullDetailsResponseCompleteHandler);
resolve();
});
gScript.sendAsyncMessage("test-init-data-and-response");
const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
ok(!payRequest.shippingOption, "payRequest.shippingOption should be null.");
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
payRequest.show(updateWithPromise(detailsUpdate)).then(response => {
if (expectedError) {
ok(false, "Should be rejected with " + expectedError + ", but got resolved");
resolve();
} else {
ok(response.shippingOption, "response.shippingOption should not be null.");
response.complete().then(() => {
resolve();
})
}
}, response => {
if (expectedError) {
is(response.name, expectedError,
"Should be rejected with " + expectedError + ", but got " + response.name);
} else {
ok(false, "Unexpected error: " + response.name);
}
resolve();
}).catch(e => {
ok(false, "Unexpected error: " + e.name);
resolve();
}).finally(handler.destruct);
});
}
function testShowWithValidPromise() {
return testShowWithDetailsPromise(updatedShippingOptionsDetails, null);
}
function testShowWithRejectedPromise() {
return testShowWithDetailsPromise(null, "AbortError");
}
function testShowWithInvalidPromise() {
return testShowWithDetailsPromise({total: "invalid details"}, "TypeError");
}
function testShowWithErrorPromise() {
return testShowWithDetailsPromise(updatedErrorDetails, "AbortError");
}
function testShowWithPromiseResolvedByRejectedPromise() {
gScript.sendAsyncMessage("set-reject-ui-service");
return new Promise((resolve, reject)=> {
const request = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
let rejectPromise = Promise.reject(new TypeError());
let detailsUpdatePromise = Promise.resolve(rejectPromise);
request.show(detailsUpdatePromise).then(response => {
ok(false, "should be rejected with 'AbortError', but got resolved.");
resolve();
}, response => {
is(response.name, "AbortError", "Exepcted 'AbortError', but got " + response.name + ".");
resolve();
}).catch(error => {
ok(false, "Unexpected error: " + error.name + ".");
}).finally(handler.destruct);
});
}
function testShowUnsafe() {
gScript.sendAsyncMessage("set-complete-ui-service");
// testing show response initialization in chrome process
function testShowResponseInit() {
return new Promise((resolve, reject) => {
gScript.addMessageListener("test-show-response-init-complete",
function showResponseInitCompleteHandler() {
gScript.removeMessageListener("test-show-response-init-complete",
showResponseInitCompleteHandler);
resolve();
});
gScript.sendAsyncMessage("test-show-response-init");
});
}
// testing show that is not triggered by user.
function testShowNotTriggeredByUser() {
gScript.sendAsyncMessage("set-simple-ui-service");
return new Promise((resolve, reject) => {
const payRequest = new PaymentRequest(defaultMethods, defaultDetails);
payRequest.show().then(() => {
@ -380,6 +423,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345366
});
}
// teardown function
function teardown() {
gScript.addMessageListener("teardown-complete", function teardownCompleteHandler() {
gScript.removeMessageListener("teardown-complete", teardownCompleteHandler);
@ -391,16 +435,26 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345366
gScript.sendAsyncMessage("teardown");
}
// test main body
function runTests() {
testCannotMakePaymentShow()
.then(testRejectShow)
.then(testShowWithSuccess)
.then(testShowWithFail)
.then(testShowWithUnknown)
.then(testShowWithEmpty)
.then(testShowNormalFlow)
.then(testCompleteSuccess)
.then(testCompleteFail)
.then(testCompleteUnknown)
.then(testCompleteEmpty)
.then(testUpdateWithReject)
.then(testUpdateWithValidDetails)
.then(testUpdateWithInvalidDetails)
.then(testUpdateWithError)
.then(testNullDetailsResponse)
.then(testShowUnsafe)
.then(testShowWithValidPromise)
.then(testShowWithInvalidPromise)
.then(testShowWithRejectedPromise)
.then(testShowWithErrorPromise)
.then(testShowWithPromiseResolvedByRejectedPromise)
.then(testShowResponseInit)
.then(testShowNotTriggeredByUser)
.then(teardown)
.catch( e => {
ok(false, "Unexpected error: " + e.name);

Просмотреть файл

@ -2083,8 +2083,8 @@ ServiceWorkerManager::RemoveScopeAndRegistration(ServiceWorkerRegistrationInfo*
auto& reg = iter.UserData()->mRegistrationInfo;
if (reg->Scope().Equals(aRegistration->Scope()) &&
reg->Principal()->Equals(aRegistration->Principal())) {
MOZ_DIAGNOSTIC_ASSERT(false,
"controlled client when removing registration");
MOZ_DIAGNOSTIC_ASSERT(aRegistration->IsCorrupt(),
"controlled client when removing non-corrupt registration");
iter.Remove();
break;
}

Просмотреть файл

@ -198,7 +198,7 @@ private:
nsresult
ServiceWorkerPrivate::CheckScriptEvaluation(LifeCycleEventCallback* aScriptEvaluationCallback)
{
nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent, nullptr);
nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent);
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
@ -571,7 +571,7 @@ ServiceWorkerPrivate::SendMessageEvent(JSContext* aCx,
{
MOZ_ASSERT(NS_IsMainThread());
ErrorResult rv(SpawnWorkerIfNeeded(MessageEvent, nullptr));
ErrorResult rv(SpawnWorkerIfNeeded(MessageEvent));
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
}
@ -834,10 +834,9 @@ LifecycleEventWorkerRunnable::DispatchLifecycleEvent(JSContext* aCx,
nsresult
ServiceWorkerPrivate::SendLifeCycleEvent(const nsAString& aEventType,
LifeCycleEventCallback* aCallback,
nsIRunnable* aLoadFailure)
LifeCycleEventCallback* aCallback)
{
nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent, aLoadFailure);
nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent);
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
@ -1023,7 +1022,7 @@ ServiceWorkerPrivate::SendPushEvent(const nsAString& aMessageId,
const Maybe<nsTArray<uint8_t>>& aData,
ServiceWorkerRegistrationInfo* aRegistration)
{
nsresult rv = SpawnWorkerIfNeeded(PushEvent, nullptr);
nsresult rv = SpawnWorkerIfNeeded(PushEvent);
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
@ -1055,7 +1054,7 @@ ServiceWorkerPrivate::SendPushEvent(const nsAString& aMessageId,
nsresult
ServiceWorkerPrivate::SendPushSubscriptionChangeEvent()
{
nsresult rv = SpawnWorkerIfNeeded(PushSubscriptionChangeEvent, nullptr);
nsresult rv = SpawnWorkerIfNeeded(PushSubscriptionChangeEvent);
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
@ -1314,7 +1313,7 @@ ServiceWorkerPrivate::SendNotificationEvent(const nsAString& aEventName,
return NS_ERROR_FAILURE;
}
nsresult rv = SpawnWorkerIfNeeded(why, nullptr);
nsresult rv = SpawnWorkerIfNeeded(why);
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
@ -1751,19 +1750,11 @@ ServiceWorkerPrivate::SendFetchEvent(nsIInterceptedChannel* aChannel,
return NS_OK;
}
// if the ServiceWorker script fails to load for some reason, just resume
// the original channel.
nsCOMPtr<nsIRunnable> failRunnable =
NewRunnableMethod("nsIInterceptedChannel::ResetInterception",
aChannel,
&nsIInterceptedChannel::ResetInterception);
aChannel->SetLaunchServiceWorkerStart(TimeStamp::Now());
aChannel->SetDispatchFetchEventStart(TimeStamp::Now());
bool newWorkerCreated = false;
nsresult rv = SpawnWorkerIfNeeded(FetchEvent,
failRunnable,
&newWorkerCreated,
aLoadGroup);
NS_ENSURE_SUCCESS(rv, rv);
@ -1808,7 +1799,6 @@ ServiceWorkerPrivate::SendFetchEvent(nsIInterceptedChannel* aChannel,
nsresult
ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
nsIRunnable* aLoadFailedRunnable,
bool* aNewWorkerCreated,
nsILoadGroup* aLoadGroup)
{
@ -1872,7 +1862,6 @@ ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
info.mServiceWorkerRegistrationDescriptor.emplace(reg->Descriptor());
info.mLoadGroup = aLoadGroup;
info.mLoadFailedAsyncRunnable = aLoadFailedRunnable;
// If we are loading a script for a ServiceWorker then we must not
// try to intercept it. If the interception matches the current
@ -2095,7 +2084,7 @@ ServiceWorkerPrivate::AttachDebugger()
// and cancel the idle timeout. The idle timeout should not be reset until
// the last debugger detached from the worker.
if (!mDebuggerCount) {
nsresult rv = SpawnWorkerIfNeeded(AttachEvent, nullptr);
nsresult rv = SpawnWorkerIfNeeded(AttachEvent);
NS_ENSURE_SUCCESS(rv, rv);
mIdleWorkerTimer->Cancel();

Просмотреть файл

@ -93,8 +93,7 @@ public:
nsresult
SendLifeCycleEvent(const nsAString& aEventType,
LifeCycleEventCallback* aCallback,
nsIRunnable* aLoadFailure);
LifeCycleEventCallback* aCallback);
nsresult
SendPushEvent(const nsAString& aMessageId,
@ -190,11 +189,8 @@ private:
void
ReleaseToken();
// |aLoadFailedRunnable| is a runnable dispatched to the main thread
// if the script loader failed for some reason, but can be null.
nsresult
SpawnWorkerIfNeeded(WakeUpReason aWhy,
nsIRunnable* aLoadFailedRunnable,
bool* aNewWorkerCreated = nullptr,
nsILoadGroup* aLoadGroup = nullptr);

Просмотреть файл

@ -80,6 +80,19 @@ ServiceWorkerRegistrationInfo::Clear()
NotifyChromeRegistrationListeners();
}
void
ServiceWorkerRegistrationInfo::ClearAsCorrupt()
{
mCorrupt = true;
Clear();
}
bool
ServiceWorkerRegistrationInfo::IsCorrupt() const
{
return mCorrupt;
}
ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(
const nsACString& aScope,
nsIPrincipal* aPrincipal,
@ -93,6 +106,7 @@ ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(
, mCreationTimeStamp(TimeStamp::Now())
, mLastUpdateTime(0)
, mPendingUninstall(false)
, mCorrupt(false)
{}
ServiceWorkerRegistrationInfo::~ServiceWorkerRegistrationInfo()
@ -308,12 +322,6 @@ ServiceWorkerRegistrationInfo::Activate()
MOZ_DIAGNOSTIC_ASSERT(mActiveWorker);
swm->UpdateClientControllers(this);
nsCOMPtr<nsIRunnable> failRunnable = NewRunnableMethod<bool>(
"dom::ServiceWorkerRegistrationInfo::FinishActivate",
this,
&ServiceWorkerRegistrationInfo::FinishActivate,
false /* success */);
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> handle(
new nsMainThreadPtrHolder<ServiceWorkerRegistrationInfo>(
"ServiceWorkerRegistrationInfoProxy", this));
@ -322,9 +330,14 @@ ServiceWorkerRegistrationInfo::Activate()
ServiceWorkerPrivate* workerPrivate = mActiveWorker->WorkerPrivate();
MOZ_ASSERT(workerPrivate);
nsresult rv = workerPrivate->SendLifeCycleEvent(NS_LITERAL_STRING("activate"),
callback, failRunnable);
callback);
if (NS_WARN_IF(NS_FAILED(rv))) {
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(failRunnable));
nsCOMPtr<nsIRunnable> failRunnable = NewRunnableMethod<bool>(
"dom::ServiceWorkerRegistrationInfo::FinishActivate",
this,
&ServiceWorkerRegistrationInfo::FinishActivate,
false /* success */);
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(failRunnable.forget()));
return;
}
}

Просмотреть файл

@ -50,6 +50,8 @@ class ServiceWorkerRegistrationInfo final
// pendingUninstall and when all controlling documents go away, removed.
bool mPendingUninstall;
bool mCorrupt;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISERVICEWORKERREGISTRATIONINFO
@ -114,6 +116,12 @@ public:
void
Clear();
void
ClearAsCorrupt();
bool
IsCorrupt() const;
void
TryToActivateAsync();

Просмотреть файл

@ -300,6 +300,7 @@ public:
, mLoadFlags(nsIChannel::LOAD_BYPASS_SERVICE_WORKER)
, mState(WaitingForInitialization)
, mPendingCount(0)
, mOnFailure(OnFailure::DoNothing)
, mAreScriptsEqual(true)
{
MOZ_ASSERT(NS_IsMainThread());
@ -360,6 +361,7 @@ public:
MOZ_ASSERT(mCallback);
mCallback->ComparisonResult(aStatus,
true /* aSameScripts */,
mOnFailure,
EmptyString(),
mMaxScope,
mLoadFlags);
@ -476,16 +478,10 @@ private:
mState = WaitingForScriptOrComparisonResult;
// Always make sure to fetch the main script. If the old cache has
// no entries or the main script entry is missing, then the loop below
// may not trigger it. This should not really happen, but we handle it
// gracefully if it does occur. Its possible the bad cache state is due
// to a crash or shutdown during an update, etc.
rv = FetchScript(mURL, true /* aIsMainScript */, mOldCache);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
bool hasMainScript = false;
AutoTArray<nsString, 8> urlList;
// Extract the list of URLs in the old cache.
for (uint32_t i = 0; i < len; ++i) {
JS::Rooted<JS::Value> val(aCx);
if (NS_WARN_IF(!JS_GetElement(aCx, obj, i, &val)) ||
@ -499,15 +495,41 @@ private:
return;
};
nsString URL;
request->GetUrl(URL);
nsString url;
request->GetUrl(url);
if (!hasMainScript && url == mURL) {
hasMainScript = true;
}
urlList.AppendElement(url);
}
// If the main script is missing, then something has gone wrong. We
// will try to continue with the update process to trigger a new
// installation. If that fails, however, then uninstall the registration
// because it is broken in a way that cannot be fixed.
if (!hasMainScript) {
mOnFailure = OnFailure::Uninstall;
}
// Always make sure to fetch the main script. If the old cache has
// no entries or the main script entry is missing, then the loop below
// may not trigger it. This should not really happen, but we handle it
// gracefully if it does occur. Its possible the bad cache state is due
// to a crash or shutdown during an update, etc.
rv = FetchScript(mURL, true /* aIsMainScript */, mOldCache);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
for (const auto& url : urlList) {
// We explicitly start the fetch for the main script above.
if (mURL == URL) {
if (mURL == url) {
continue;
}
rv = FetchScript(URL, false /* aIsMainScript */, mOldCache);
rv = FetchScript(url, false /* aIsMainScript */, mOldCache);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
@ -674,6 +696,7 @@ private:
} mState;
uint32_t mPendingCount;
OnFailure mOnFailure;
bool mAreScriptsEqual;
};
@ -1326,6 +1349,7 @@ CompareManager::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
if (--mPendingCount == 0) {
mCallback->ComparisonResult(NS_OK,
false /* aIsEqual */,
mOnFailure,
mNewCacheName,
mMaxScope,
mLoadFlags);
@ -1367,7 +1391,7 @@ void
CompareManager::Fail(nsresult aStatus)
{
MOZ_ASSERT(NS_IsMainThread());
mCallback->ComparisonResult(aStatus, false /* aIsEqual */,
mCallback->ComparisonResult(aStatus, false /* aIsEqual */, mOnFailure,
EmptyString(), EmptyCString(), mLoadFlags);
Cleanup();
}

Просмотреть файл

@ -25,9 +25,15 @@ PurgeCache(nsIPrincipal* aPrincipal, const nsAString& aCacheName);
nsresult
GenerateCacheName(nsAString& aName);
enum class OnFailure : uint8_t {
DoNothing,
Uninstall
};
class CompareCallback
{
public:
/*
* If there is an error, ignore aInCacheAndEqual and aNewCacheName.
* On success, if the cached result and network result matched,
@ -37,6 +43,7 @@ public:
virtual void
ComparisonResult(nsresult aStatus,
bool aInCacheAndEqual,
OnFailure aOnFailure,
const nsAString& aNewCacheName,
const nsACString& aMaxScope,
nsLoadFlags aLoadFlags) = 0;

Просмотреть файл

@ -14,6 +14,8 @@
namespace mozilla {
namespace dom {
using serviceWorkerScriptCache::OnFailure;
namespace {
/**
@ -96,12 +98,14 @@ public:
virtual void
ComparisonResult(nsresult aStatus,
bool aInCacheAndEqual,
OnFailure aOnFailure,
const nsAString& aNewCacheName,
const nsACString& aMaxScope,
nsLoadFlags aLoadFlags) override
{
mJob->ComparisonResult(aStatus,
aInCacheAndEqual,
aOnFailure,
aNewCacheName,
aMaxScope,
aLoadFlags);
@ -177,6 +181,7 @@ ServiceWorkerUpdateJob::ServiceWorkerUpdateJob(
: ServiceWorkerJob(Type::Update, aPrincipal, aScope, aScriptSpec)
, mLoadGroup(aLoadGroup)
, mUpdateViaCache(aUpdateViaCache)
, mOnFailure(OnFailure::DoNothing)
{
}
@ -212,20 +217,37 @@ ServiceWorkerUpdateJob::FailUpdateJob(ErrorResult& aRv)
MOZ_ASSERT(aRv.Failed());
// Cleanup after a failed installation. This essentially implements
// step 12 of the Install algorithm.
// step 13 of the Install algorithm.
//
// https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#installation-algorithm
// https://w3c.github.io/ServiceWorker/#installation-algorithm
//
// The spec currently only runs this after an install event fails,
// but we must handle many more internal errors. So we check for
// cleanup on every non-successful exit.
if (mRegistration) {
mRegistration->ClearEvaluating();
mRegistration->ClearInstalling();
// Some kinds of failures indicate there is something broken in the currently
// installed registration. In these cases we want to fully unregister.
if (mOnFailure == OnFailure::Uninstall) {
mRegistration->ClearAsCorrupt();
}
// Otherwise just clear the workers we may have created as part of the
// update process.
else {
mRegistration->ClearEvaluating();
mRegistration->ClearInstalling();
}
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
if (swm) {
swm->MaybeRemoveRegistration(mRegistration);
// Also clear the registration on disk if we are forcing uninstall
// due to a particularly bad failure.
if (mOnFailure == OnFailure::Uninstall) {
swm->MaybeSendUnregister(mRegistration->Principal(),
mRegistration->Scope());
}
}
}
@ -337,12 +359,15 @@ ServiceWorkerUpdateJob::GetUpdateViaCache() const
void
ServiceWorkerUpdateJob::ComparisonResult(nsresult aStatus,
bool aInCacheAndEqual,
OnFailure aOnFailure,
const nsAString& aNewCacheName,
const nsACString& aMaxScope,
nsLoadFlags aLoadFlags)
{
MOZ_ASSERT(NS_IsMainThread());
mOnFailure = aOnFailure;
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
if (NS_WARN_IF(Canceled() || !swm)) {
FailUpdateJob(NS_ERROR_DOM_ABORT_ERR);
@ -440,6 +465,14 @@ ServiceWorkerUpdateJob::ComparisonResult(nsresult aStatus,
aNewCacheName,
flags);
// If the registration is corrupt enough to force an uninstall if the
// upgrade fails, then we want to make sure the upgrade takes effect
// if it succeeds. Therefore force the skip-waiting flag on to replace
// the broken worker after install.
if (aOnFailure == OnFailure::Uninstall) {
sw->SetSkipWaitingFlag();
}
mRegistration->SetEvaluating(sw);
nsMainThreadPtrHandle<ServiceWorkerUpdateJob> handle(
@ -515,14 +548,6 @@ ServiceWorkerUpdateJob::Install(ServiceWorkerManager* aSWM)
mRegistration);
NS_DispatchToMainThread(upr);
// Call ContinueAfterInstallEvent(false) on main thread if the SW
// script fails to load.
nsCOMPtr<nsIRunnable> failRunnable = NewRunnableMethod<bool>(
"dom::ServiceWorkerUpdateJob::ContinueAfterInstallEvent",
this,
&ServiceWorkerUpdateJob::ContinueAfterInstallEvent,
false);
nsMainThreadPtrHandle<ServiceWorkerUpdateJob> handle(
new nsMainThreadPtrHolder<ServiceWorkerUpdateJob>(
"ServiceWorkerUpdateJob", this));
@ -532,7 +557,7 @@ ServiceWorkerUpdateJob::Install(ServiceWorkerManager* aSWM)
ServiceWorkerPrivate* workerPrivate =
mRegistration->GetInstalling()->WorkerPrivate();
nsresult rv = workerPrivate->SendLifeCycleEvent(NS_LITERAL_STRING("install"),
callback, failRunnable);
callback);
if (NS_WARN_IF(NS_FAILED(rv))) {
ContinueAfterInstallEvent(false /* aSuccess */);
}

Просмотреть файл

@ -13,6 +13,10 @@
namespace mozilla {
namespace dom {
namespace serviceWorkerScriptCache {
enum class OnFailure : uint8_t;
} // namespace serviceWorkerScriptCache
class ServiceWorkerManager;
// A job class that performs the Update and Install algorithms from the
@ -83,6 +87,7 @@ private:
void
ComparisonResult(nsresult aStatus,
bool aInCacheAndEqual,
serviceWorkerScriptCache::OnFailure aOnFailure,
const nsAString& aNewCacheName,
const nsACString& aMaxScope,
nsLoadFlags aLoadFlags);
@ -99,10 +104,10 @@ private:
void
ContinueAfterInstallEvent(bool aInstallEventSuccess);
RefPtr<ServiceWorkerRegistrationInfo> mRegistration;
nsCOMPtr<nsILoadGroup> mLoadGroup;
ServiceWorkerUpdateViaCache mUpdateViaCache;
RefPtr<ServiceWorkerRegistrationInfo> mRegistration;
serviceWorkerScriptCache::OnFailure mOnFailure;
};
} // namespace dom

Просмотреть файл

@ -12,6 +12,7 @@ support-files =
force_refresh_browser_worker.js
empty.html
empty.js
storage_recovery_worker.sjs
utils.js
[browser_devtools_serviceworker_interception.js]
@ -19,6 +20,7 @@ support-files =
[browser_download.js]
[browser_download_canceled.js]
[browser_storage_permission.js]
[browser_storage_recovery.js]
[browser_unregister_with_containers.js]
[browser_userContextId_openWindow.js]
skip-if = !e10s

Просмотреть файл

@ -0,0 +1,146 @@
"use strict";
// This test registers a SW for a scope that will never control a document
// and therefore never trigger a "fetch" functional event that would
// automatically attempt to update the registration. The overlap of the
// PAGE_URI and SCOPE is incidental. checkForUpdate is the only thing that
// will trigger an update of the registration and so there is no need to
// worry about Schedule Job races to coalesce an update job.
const BASE_URI = "http://mochi.test:8888/browser/dom/serviceworkers/test/";
const PAGE_URI = BASE_URI + "empty.html";
const SCOPE = PAGE_URI + "?storage_recovery";
const SW_SCRIPT = BASE_URI + "storage_recovery_worker.sjs";
async function checkForUpdate(browser) {
return ContentTask.spawn(browser, SCOPE, async function(uri) {
let reg = await content.navigator.serviceWorker.getRegistration(uri);
await reg.update();
return !!reg.installing;
});
}
// Delete all of our chrome-namespace Caches for this origin, leaving any
// content-owned caches in place. This is exclusively for simulating loss
// of the origin's storage without loss of the registration and without
// having to worry that future enhancements to QuotaClients/ServiceWorkerRegistrar
// will break this test. If you want to wipe storage for an origin, use
// QuotaManager APIs
async function wipeStorage(u) {
let uri = Services.io.newURI(u);
let principal =
Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
let caches = new CacheStorage("chrome", principal);
let list = await caches.keys();
return Promise.all(list.map(c => caches.delete(c)));
}
add_task(async function setup() {
await SpecialPowers.pushPrefEnv({"set": [
// Until the e10s refactor is complete, use a single process to avoid
// service worker propagation race.
["dom.ipc.processCount", 1],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["dom.serviceWorkers.idle_timeout", 0],
]});
// Configure the server script to not redirect.
await fetch(SW_SCRIPT + "?clear-redirect");
let tab = BrowserTestUtils.addTab(gBrowser, PAGE_URI);
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
await ContentTask.spawn(browser, { script: SW_SCRIPT, scope: SCOPE },
async function(opts) {
let reg = await content.navigator.serviceWorker.register(opts.script,
{ scope: opts.scope });
let worker = reg.installing || reg.waiting || reg.active;
await new Promise(resolve => {
if (worker.state === "activated") {
resolve();
return;
}
worker.addEventListener("statechange", function onStateChange() {
if (worker.state === "activated") {
worker.removeEventListener("statechange", onStateChange);
resolve();
}
});
});
}
);
BrowserTestUtils.removeTab(tab);
});
// Verify that our service worker doesn't update normally.
add_task(async function normal_update_check() {
let tab = BrowserTestUtils.addTab(gBrowser, PAGE_URI);
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
let updated = await checkForUpdate(browser);
ok(!updated, "normal update check should not trigger an update");
BrowserTestUtils.removeTab(tab);
});
// Test what happens when we wipe the service worker scripts
// out from under the site before triggering the update. This
// should cause an update to occur.
add_task(async function wiped_update_check() {
// Wipe the backing cache storage, but leave the SW registered.
await wipeStorage(PAGE_URI);
let tab = BrowserTestUtils.addTab(gBrowser, PAGE_URI);
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
let updated = await checkForUpdate(browser);
ok(updated, "wiping the service worker scripts should trigger an update");
BrowserTestUtils.removeTab(tab);
});
// Test what happens when we wipe the service worker scripts
// out from under the site before triggering the update. This
// should cause an update to occur.
add_task(async function wiped_and_failed_update_check() {
// Wipe the backing cache storage, but leave the SW registered.
await wipeStorage(PAGE_URI);
// Configure the service worker script to redirect. This will
// prevent the update from completing successfully.
await fetch(SW_SCRIPT + "?set-redirect");
let tab = BrowserTestUtils.addTab(gBrowser, PAGE_URI);
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
// Attempt to update the service worker. This should throw
// an error because the script is now redirecting.
let updateFailed = false;
try {
await checkForUpdate(browser);
} catch (e) {
updateFailed = true;
}
ok(updateFailed, "redirecting service worker script should fail to update");
// Also, since the existing service worker's scripts are broken
// we should also remove the registration completely when the
// update fails.
let exists = await ContentTask.spawn(browser, SCOPE, async function(uri) {
let reg = await content.navigator.serviceWorker.getRegistration(uri);
return !!reg;
});
ok(!exists, "registration should be removed after scripts are wiped and update fails");
// Note, we don't have to clean up the service worker registration
// since its effectively been force-removed here.
BrowserTestUtils.removeTab(tab);
});

Просмотреть файл

@ -0,0 +1,23 @@
const BASE_URI = "http://mochi.test:8888/browser/dom/serviceworkers/test/";
function handleRequest(request, response) {
let redirect = getState("redirect");
setState("redirect", "false");
if (request.queryString.includes("set-redirect")) {
setState("redirect", "true");
} else if (request.queryString.includes("clear-redirect")) {
setState("redirect", "false");
}
response.setHeader("Cache-Control", "no-store");
if (redirect === "true") {
response.setStatusLine(request.httpVersion, 307, "Moved Temporarily");
response.setHeader("Location", BASE_URI + "empty.js");
return;
}
response.setHeader("Content-Type", "application/javascript");
response.write("");
}

Просмотреть файл

@ -54,6 +54,11 @@ dictionary PaymentDetailsInit : PaymentDetailsBase {
required PaymentItem total;
};
dictionary PaymentDetailsUpdate : PaymentDetailsBase {
DOMString error;
PaymentItem total;
};
enum PaymentShippingType {
"shipping",
"delivery",
@ -74,7 +79,7 @@ dictionary PaymentOptions {
Func="mozilla::dom::PaymentRequest::PrefEnabled"]
interface PaymentRequest : EventTarget {
[NewObject]
Promise<PaymentResponse> show();
Promise<PaymentResponse> show(optional Promise<PaymentDetailsUpdate> detailsPromise);
[NewObject]
Promise<void> abort();
[NewObject]

Просмотреть файл

@ -7,11 +7,6 @@
* https://www.w3.org/TR/payment-request/#paymentrequestupdateevent-interface
*/
dictionary PaymentDetailsUpdate : PaymentDetailsBase {
DOMString error;
PaymentItem total;
};
[Constructor(DOMString type,
optional PaymentRequestUpdateEventInit eventInitDict),
SecureContext,

Просмотреть файл

@ -64,6 +64,7 @@
#include "mozilla/dom/ScriptLoader.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SRILogHelper.h"
#include "mozilla/dom/ServiceWorkerBinding.h"
#include "mozilla/UniquePtr.h"
#include "Principal.h"
#include "WorkerHolder.h"
@ -180,6 +181,17 @@ ChannelFromScriptURL(nsIPrincipal* principal,
aIsMainScript ? aMainScriptContentPolicyType
: nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS;
// The main service worker script should never be loaded over the network
// in this path. It should always be offlined by ServiceWorkerScriptCache.
// We assert here since this error should also be caught by the runtime
// check in CacheScriptLoader.
//
// Note, if we ever allow service worker scripts to be loaded from network
// here we need to configure the channel properly. For example, it must
// not allow redirects.
MOZ_DIAGNOSTIC_ASSERT(contentPolicyType !=
nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER);
nsCOMPtr<nsIChannel> channel;
// If we have the document, use it. Unfortunately, for dedicated workers
// 'parentDoc' ends up being the parent document, which is not the document
@ -464,6 +476,7 @@ public:
, mRunnable(aRunnable)
, mIsWorkerScript(aIsWorkerScript)
, mFailed(false)
, mState(aWorkerPrivate->GetServiceWorkerDescriptor().State())
{
MOZ_ASSERT(aWorkerPrivate);
MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
@ -496,6 +509,7 @@ private:
RefPtr<ScriptLoaderRunnable> mRunnable;
bool mIsWorkerScript;
bool mFailed;
const ServiceWorkerState mState;
nsCOMPtr<nsIInputStreamPump> mPump;
nsCOMPtr<nsIURI> mBaseURI;
mozilla::dom::ChannelInfo mChannelInfo;
@ -1757,7 +1771,20 @@ CacheScriptLoader::ResolvedCallback(JSContext* aCx,
nsresult rv;
// The ServiceWorkerScriptCache will store data for any scripts it
// it knows about. This is always at least the top level script.
// Depending on if a previous version of the service worker has
// been installed or not it may also know about importScripts(). We
// must handle loading and offlining new importScripts() here, however.
if (aValue.isUndefined()) {
// If this is the main script or we're not loading a new service worker
// then this is an error. The storage was probably wiped without
// removing the service worker registration.
if (NS_WARN_IF(mIsWorkerScript || mState != ServiceWorkerState::Parsed)) {
Fail(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
mLoadInfo.mCacheStatus = ScriptLoadInfo::ToBeCached;
rv = mRunnable->LoadScript(mIndex);
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -2047,10 +2074,6 @@ ScriptExecutorRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
if (NS_FAILED(loadInfo.mLoadResult)) {
workerinternals::ReportLoadError(mScriptLoader.mRv,
loadInfo.mLoadResult, loadInfo.mURL);
// Top level scripts only!
if (mIsWorkerScript) {
aWorkerPrivate->MaybeDispatchLoadFailedRunnable();
}
return true;
}

Просмотреть файл

@ -133,9 +133,6 @@ WorkerLoadInfo::StealFrom(WorkerLoadInfo& aOther)
MOZ_ASSERT(!mLoadGroup);
aOther.mLoadGroup.swap(mLoadGroup);
MOZ_ASSERT(!mLoadFailedAsyncRunnable);
aOther.mLoadFailedAsyncRunnable.swap(mLoadFailedAsyncRunnable);
MOZ_ASSERT(!mInterfaceRequestor);
aOther.mInterfaceRequestor.swap(mInterfaceRequestor);
@ -402,7 +399,7 @@ WorkerLoadInfo::ProxyReleaseMainThreadObjects(WorkerPrivate* aWorkerPrivate,
nsCOMPtr<nsILoadGroup>& aLoadGroupToCancel)
{
static const uint32_t kDoomedCount = 11;
static const uint32_t kDoomedCount = 10;
nsTArray<nsCOMPtr<nsISupports>> doomed(kDoomedCount);
SwapToISupportsArray(mWindow, doomed);
@ -414,7 +411,6 @@ WorkerLoadInfo::ProxyReleaseMainThreadObjects(WorkerPrivate* aWorkerPrivate,
SwapToISupportsArray(mChannel, doomed);
SwapToISupportsArray(mCSP, doomed);
SwapToISupportsArray(mLoadGroup, doomed);
SwapToISupportsArray(mLoadFailedAsyncRunnable, doomed);
SwapToISupportsArray(mInterfaceRequestor, doomed);
// Before adding anything here update kDoomedCount above!

Просмотреть файл

@ -56,12 +56,6 @@ struct WorkerLoadInfo
nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsILoadGroup> mLoadGroup;
// mLoadFailedAsyncRunnable will execute on main thread if script loading
// fails during script loading. If script loading is never started due to
// a synchronous error, then the runnable is never executed. The runnable
// is guaranteed to be released on the main thread.
nsCOMPtr<nsIRunnable> mLoadFailedAsyncRunnable;
class InterfaceRequestor final : public nsIInterfaceRequestor
{
NS_DECL_ISUPPORTS

Просмотреть файл

@ -473,6 +473,15 @@ private:
aWorkerPrivate->SetWorkerScriptExecutedSuccessfully();
return true;
}
void
PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aRunResult) override
{
if (!aRunResult) {
aWorkerPrivate->CloseInternal();
}
WorkerRunnable::PostRun(aCx, aWorkerPrivate, aRunResult);
}
};
class NotifyRunnable final : public WorkerControlRunnable
@ -3297,19 +3306,6 @@ WorkerPrivate::AfterProcessNextEvent()
MOZ_ASSERT(CycleCollectedJSContext::Get()->RecursionDepth());
}
void
WorkerPrivate::MaybeDispatchLoadFailedRunnable()
{
AssertIsOnWorkerThread();
nsCOMPtr<nsIRunnable> runnable = StealLoadFailedAsyncRunnable();
if (!runnable) {
return;
}
MOZ_ALWAYS_SUCCEEDS(DispatchToMainThread(runnable.forget()));
}
nsIEventTarget*
WorkerPrivate::MainThreadEventTarget()
{

Просмотреть файл

@ -527,9 +527,6 @@ public:
return mWorkerScriptExecutedSuccessfully;
}
void
MaybeDispatchLoadFailedRunnable();
// Get the event target to use when dispatching to the main thread
// from this Worker thread. This may be the main thread itself or
// a ThrottledEventQueue to the main thread.
@ -1056,12 +1053,6 @@ public:
return mLoadInfo.mServiceWorkersTestingInWindow;
}
already_AddRefed<nsIRunnable>
StealLoadFailedAsyncRunnable()
{
return mLoadInfo.mLoadFailedAsyncRunnable.forget();
}
// This is used to handle importScripts(). When the worker is first loaded
// and executed, it happens in a sync loop. At this point it sets
// mLoadingWorkerScript to true. importScripts() calls that occur during the

Просмотреть файл

@ -598,7 +598,7 @@ DoGetElemFallback(JSContext* cx, BaselineFrame* frame, ICGetElem_Fallback* stub_
BaselineCacheIRStubKind::Monitored,
engine, script, stub, &attached);
if (newStub) {
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached GetElem CacheIR stub");
if (gen.shouldNotePreliminaryObjectStub())
newStub->toCacheIR_Monitored()->notePreliminaryObject();
else if (gen.shouldUnlinkPreliminaryObjectStubs())
@ -671,7 +671,7 @@ DoGetElemSuperFallback(JSContext* cx, BaselineFrame* frame, ICGetElem_Fallback*
BaselineCacheIRStubKind::Monitored,
engine, script, stub, &attached);
if (newStub) {
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached GetElemSuper CacheIR stub");
if (gen.shouldNotePreliminaryObjectStub())
newStub->toCacheIR_Monitored()->notePreliminaryObject();
else if (gen.shouldUnlinkPreliminaryObjectStubs())
@ -841,7 +841,7 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_
ICStubEngine::Baseline, frame->script(),
stub, &attached);
if (newStub) {
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached SetElem CacheIR stub");
SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo());
@ -910,7 +910,7 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_
else if (gen.shouldUnlinkPreliminaryObjectStubs())
StripPreliminaryObjectStubs(cx, stub);
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached SetElem CacheIR stub");
SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo());
return true;
}
@ -1102,7 +1102,7 @@ DoInFallback(JSContext* cx, BaselineFrame* frame, ICIn_Fallback* stub_,
BaselineCacheIRStubKind::Regular,
engine, script, stub, &attached);
if (newStub)
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached In CacheIR stub");
}
if (!attached)
stub->state().trackNotAttached();
@ -1171,7 +1171,7 @@ DoHasOwnFallback(JSContext* cx, BaselineFrame* frame, ICHasOwn_Fallback* stub_,
BaselineCacheIRStubKind::Regular,
engine, script, stub, &attached);
if (newStub)
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached HasOwn CacheIR stub");
}
if (!attached)
stub->state().trackNotAttached();
@ -1243,7 +1243,7 @@ DoGetNameFallback(JSContext* cx, BaselineFrame* frame, ICGetName_Fallback* stub_
BaselineCacheIRStubKind::Monitored,
engine, script, stub, &attached);
if (newStub)
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached GetName CacheIR stub");
}
if (!attached)
stub->state().trackNotAttached();
@ -1324,7 +1324,7 @@ DoBindNameFallback(JSContext* cx, BaselineFrame* frame, ICBindName_Fallback* stu
ICStubEngine::Baseline, script, stub,
&attached);
if (newStub)
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached BindName CacheIR stub");
}
if (!attached)
stub->state().trackNotAttached();
@ -1402,7 +1402,7 @@ DoGetIntrinsicFallback(JSContext* cx, BaselineFrame* frame, ICGetIntrinsic_Fallb
ICStubEngine::Baseline, script, stub,
&attached);
if (newStub)
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached GetIntrinsic CacheIR stub");
}
if (!attached)
stub->state().trackNotAttached();
@ -1500,7 +1500,7 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
ICStubEngine::Baseline, frame->script(),
stub, &attached);
if (newStub) {
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached SetProp CacheIR stub");
SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo());
@ -1577,7 +1577,7 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
else if (gen.shouldUnlinkPreliminaryObjectStubs())
StripPreliminaryObjectStubs(cx, stub);
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached SetProp CacheIR stub");
SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo());
}
} else {
@ -2334,7 +2334,7 @@ DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub_, uint
script, stub, &handled);
if (newStub) {
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached Call CacheIR stub");
// If it's an updated stub, initialize it.
if (gen.cacheIRStubKind() == BaselineCacheIRStubKind::Updated)
@ -3936,7 +3936,7 @@ DoGetIteratorFallback(JSContext* cx, BaselineFrame* frame, ICGetIterator_Fallbac
BaselineCacheIRStubKind::Regular,
engine, script, stub, &attached);
if (newStub)
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached GetIterator CacheIR stub");
}
if (!attached)
stub->state().trackNotAttached();
@ -4237,7 +4237,7 @@ DoTypeOfFallback(JSContext* cx, BaselineFrame* frame, ICTypeOf_Fallback* stub, H
BaselineCacheIRStubKind::Regular,
engine, script, stub, &attached);
if (newStub)
JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub");
JitSpew(JitSpew_BaselineIC, " Attached TypeOf CacheIR stub");
}
if (!attached)
stub->state().trackNotAttached();
@ -4590,7 +4590,7 @@ DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame, ICUnaryArith_Fallback*
BaselineCacheIRStubKind::Regular,
ICStubEngine::Baseline, script, stub, &attached);
if (newStub) {
JitSpew(JitSpew_BaselineIC, " Attached (shared) CacheIR stub for %s", CodeName[op]);
JitSpew(JitSpew_BaselineIC, " Attached UnaryArith CacheIR stub for %s", CodeName[op]);
}
}
}

Просмотреть файл

@ -843,7 +843,14 @@ js::wasm::StartUnwinding(const RegisterState& registers, UnwindState* unwindStat
case CodeRange::BuiltinThunk:
case CodeRange::DebugTrap:
#if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
if (offsetFromEntry < PushedFP || codeRange->isThunk()) {
if (codeRange->isThunk()) {
// The FarJumpIsland sequence temporary scrambles ra.
// Don't unwind to caller.
fixedPC = pc;
fixedFP = fp;
*unwoundCaller = false;
AssertMatchesCallSite(fp->returnAddress, fp->callerFP);
} else if (offsetFromEntry < PushedFP) {
// On MIPS we rely on register state instead of state saved on
// stack until the wasm::Frame is completely built.
// On entry the return address is in ra (registers.lr) and

Просмотреть файл

@ -23,7 +23,8 @@ namespace dom {
MediaQueryList::MediaQueryList(nsIDocument* aDocument,
const nsAString& aMediaQueryList,
CallerType aCallerType)
: mDocument(aDocument)
: DOMEventTargetHelper(aDocument->GetInnerWindow())
, mDocument(aDocument)
, mMatches(false)
, mMatchesValid(false)
{

Просмотреть файл

@ -1052,6 +1052,9 @@ public:
nsresult rv = NS_ReadInputStreamToString(mMsg.pStream, *temp, mLength);
NS_ENSURE_SUCCESS(rv, rv);
if (temp->Length() != mLength) {
return NS_ERROR_UNEXPECTED;
}
mMsg.pStream->Close();
mMsg.pStream->Release();

Просмотреть файл

@ -1163,4 +1163,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1531102070607000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1531169998600000);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -8,7 +8,7 @@
/*****************************************************************************/
#include <stdint.h>
const PRTime gPreloadListExpirationTime = INT64_C(1533521257162000);
const PRTime gPreloadListExpirationTime = INT64_C(1533589185229000);
%%
0-1.party, 1
0.me.uk, 1
@ -82,7 +82,6 @@ const PRTime gPreloadListExpirationTime = INT64_C(1533521257162000);
0573wk.com, 1
066318.com, 1
066538.com, 1
066718.com, 1
06se.com, 1
070709.net, 1
07733.win, 1
@ -445,7 +444,6 @@ const PRTime gPreloadListExpirationTime = INT64_C(1533521257162000);
3056999.com, 1
309422.com, 1
30hzcollective.com, 1
30yearmortgagerates.net, 1
310422.com, 1
3133780x.com, 1
313422.com, 1
@ -529,6 +527,7 @@ const PRTime gPreloadListExpirationTime = INT64_C(1533521257162000);
3555500.com, 1
356433.com, 1
360ds.co.in, 1
360live.fr, 1
360woodworking.com, 1
365365.com, 1
365beautyworld.com, 1
@ -1220,7 +1219,7 @@ aboutyou.de, 1
aboutyou.nl, 1
abox-kb.com, 1
abpis.hr, 1
abracadabra.co.jp, 1
abracadabra.co.jp, 0
abrakidabra.com.br, 1
abrilect.com, 1
abseits.org, 1
@ -1472,6 +1471,7 @@ adorecricket.com, 1
adorewe.com, 1
adoriasoft.com, 0
adoucisseur.shop, 1
adprospb.com, 1
adquisitio.co.uk, 1
adquisitio.es, 1
adquisitio.fr, 1
@ -1564,6 +1564,7 @@ aergia.eu, 1
aerisnetwork.com, 1
aero-pioneer.com, 1
aerobotz.com, 1
aeroparking.es, 1
aertel.ie, 1
aessencia.com.br, 1
aestheticdr.org, 1
@ -2239,7 +2240,6 @@ american.dating, 1
americandistribuidora.com, 1
americanfoundationbr.com, 1
americanmediainstitute.com, 1
americanoutlawjeepparts.com, 1
americasbasementcontractor.com, 1
americkykongres.cz, 1
amerigroup.com, 1
@ -2574,6 +2574,7 @@ antennista.milano.it, 1
antennista.pavia.it, 1
antennista.roma.it, 1
antennisti.milano.it, 1
anthedesign.fr, 1
anthisis.tv, 1
anthony-rouanet.com, 1
anthony.codes, 1
@ -3531,7 +3532,6 @@ b-b-law.com, 1
b-boom.nl, 1
b-cyclesshop.ch, 1
b-entropy.com, 1
b-landia.net, 0
b-pi.duckdns.org, 1
b-root-force.de, 1
b-services.net, 1
@ -3785,6 +3785,7 @@ ballotapi.com, 1
ballothero.com, 1
ballroom.info, 1
balonmano.co, 1
bals.org, 1
balslev.io, 1
balticnetworks.com, 1
bambambaby.com.br, 1
@ -3872,7 +3873,6 @@ barkerjr.xyz, 1
barlotta.net, 1
barnabycolby.io, 1
barnrats.com, 1
baropkamp.be, 1
barprive.com, 1
barqo.co, 1
barracuda.blog, 1
@ -4579,7 +4579,6 @@ bilimoe.com, 1
bilke.org, 1
bill-nye-the.science, 1
billaud.eu.org, 1
billdestler.com, 1
billgoldstein.name, 1
billhartzer.com, 1
billiger-mietwagen.de, 1
@ -4828,6 +4827,24 @@ bl4ckb0x.eu, 1
bl4ckb0x.info, 1
bl4ckb0x.net, 1
bl4ckb0x.org, 1
blablacar.co.uk, 1
blablacar.com, 1
blablacar.com.tr, 1
blablacar.com.ua, 1
blablacar.de, 1
blablacar.es, 1
blablacar.fr, 1
blablacar.hr, 1
blablacar.hu, 1
blablacar.in, 1
blablacar.it, 1
blablacar.mx, 1
blablacar.nl, 1
blablacar.pl, 1
blablacar.pt, 1
blablacar.ro, 1
blablacar.rs, 1
blablacar.ru, 1
black-gay-porn.biz, 1
black-khat.com, 1
black-mail.nl, 1
@ -4966,6 +4983,7 @@ blogpentrusuflet.ro, 1
blogreen.org, 1
blogtroterzy.pl, 1
bloodsports.org, 1
bloodyexcellent.com, 1
bloom-avenue.com, 1
bltc.co.uk, 1
bltc.com, 1
@ -4987,6 +5005,7 @@ blued.moe, 1
bluedeck.org, 1
bluefinger.nl, 1
blueflare.org, 1
bluefrag.com, 1
bluefuzz.nl, 1
blueimp.net, 1
blueliquiddesigns.com.au, 1
@ -5133,6 +5152,7 @@ bondskampeerder.nl, 1
bondtofte.dk, 1
bonesserver.com, 1
bonfi.net, 1
bonibuty.com, 1
bonifacius.be, 1
bonigo.de, 1
bonita.com.br, 1
@ -5171,8 +5191,6 @@ booktracker-org.appspot.com, 1
bookwitty.social, 1
bool.be, 1
boomersurf.com, 1
boomsaki.com, 1
boomsakis.com, 1
boomshelf.com, 1
boomshelf.org, 1
boonbox.com, 1
@ -6519,7 +6537,6 @@ censurfridns.nu, 1
censys.io, 1
centaur.de, 1
centennialradon.com, 1
centerforpolicy.org, 1
centerpereezd.ru, 0
centerpoint.ovh, 1
centillien.com, 0
@ -7712,7 +7729,6 @@ compilenix.org, 1
completefloorcoverings.com, 1
completesecurityessex.co.uk, 1
completesecurityessex.com, 1
completionist.me, 1
complex-organization.com, 1
complexart.ro, 1
complexsystems.fail, 1
@ -8713,6 +8729,7 @@ danieljamesscott.org, 1
danieljireh.com, 1
danielkoster.nl, 1
danielmarquard.com, 1
danielmoch.com, 1
danielmostertman.com, 0
danielmostertman.nl, 0
danielrozenberg.com, 1
@ -9666,7 +9683,6 @@ directorioz.com, 1
directreal.sk, 1
directspa.fr, 1
directtwo.solutions, 1
directtwosolutions.org, 1
directwatertanks.co.uk, 1
direwolfsoftware.ca, 1
dirips.com, 1
@ -10003,7 +10019,6 @@ donateaday.net, 1
donfelino.tk, 0
dongkexue.com, 1
dongxuwang.com, 1
donhoward.org, 1
donkeytrekkingkefalonia.com, 1
donmaldeamores.com, 1
donnachie.net, 1
@ -10369,7 +10384,6 @@ dujsq.top, 1
dukan-recepty.ru, 1
dukegat.de, 0
dukesatqueens.com, 1
duks.com.br, 1
dukun.de, 1
dulei.si, 1
dullapp.com, 1
@ -10416,6 +10430,7 @@ dustygroove.com, 1
dustyspokesbnb.ca, 1
dutch.desi, 1
dutch1.nl, 1
dutchessuganda.com, 1
dutchrank.nl, 1
dutchwanderers.nl, 1
dutchweballiance.nl, 1
@ -10773,7 +10788,6 @@ edwinyrkuniversity.de, 1
edxg.de, 0
edxn.de, 1
edyou.eu, 1
edzilla.info, 1
ee-terminals.com, 1
eeb98.com, 1
eeetrust.org, 1
@ -12208,6 +12222,7 @@ falconvintners.com, 1
falcoz.co, 1
faldoria.de, 0
falegname-roma.it, 1
falkhusemann.de, 1
falkus.net, 1
falldennismarketing.com, 1
fallenangeldrinks.co.uk, 1
@ -12493,7 +12508,6 @@ ferticare.pt, 1
fertila.de, 1
festaprylar.se, 1
festival-tipps.com, 1
festival.house, 1
festivaljapon.com, 1
festivalxdentro.com, 1
fetch.co.uk, 1
@ -13705,6 +13719,7 @@ gamepad.com.br, 1
gamercredo.com, 1
gamereader.de, 1
gamerezo.com, 1
gamerpoets.com, 1
gamerz-stream.com, 1
gamerzdot.com, 1
games4theworld.org, 1
@ -14274,7 +14289,6 @@ glicerina.online, 1
glidingshop.cz, 1
glidingshop.de, 1
glidingshop.eu, 1
glittersjabloon.nl, 1
glloq.org, 1
glob-coin.com, 1
global-adult-webcams.com, 1
@ -15812,6 +15826,7 @@ hogrebe.de, 1
hohm.in, 1
hohnet.com, 1
hoikuen-now.top, 1
hoiquanadida.com, 1
hoken-wakaru.jp, 1
hokepon.com, 1
hokieprivacy.org, 1
@ -15962,6 +15977,7 @@ hostadvice.com, 1
hostam.link, 1
hostarea51.com, 1
hostcoz.com, 1
hosteasy.nl, 0
hosted-oswa.org, 1
hostedbgp.net, 1
hostedcomments.com, 1
@ -16530,7 +16546,6 @@ ig.com, 1
iga-semi.jp, 1
igamingforums.com, 1
igcc.jp, 1
igd.chat, 1
igglabs.com, 1
iggprivate.com, 1
iggsoft.com, 1
@ -19772,6 +19787,7 @@ langly.fr, 1
langstreckensaufen.de, 1
languageterminal.com, 1
langworth.com, 1
laniakean.com, 1
lanna.io, 1
lannainnovation.com, 1
lanonfire.com, 1
@ -20515,6 +20531,7 @@ lionlyrics.com, 1
lionsdeal.com, 1
lipartydepot.com, 1
lipex.com, 1
lipo.lol, 1
lipoabaltimore.org, 1
liqd.net, 1
liquid.cz, 1
@ -20611,6 +20628,7 @@ livepaperhelp.com, 1
livepath.ch, 1
liveperformersmeeting.net, 1
liveregistratie.nl, 1
livesearch-fukuoka.com, 1
livesure.com, 1
livi.co, 1
living-space.co.nz, 1
@ -20796,7 +20814,6 @@ lolicon.eu, 1
lolicon.info, 1
lolis.stream, 1
lolkot.ru, 1
lollaconcept.com.br, 1
lolnames.gg, 1
lolpatrol.de, 1
lolpatrol.wtf, 1
@ -21474,7 +21491,7 @@ manuel-herrmann.de, 1
manuel-schefczyk.de, 1
manueldopheide.com, 1
manueli.de, 1
manuelpinto.in, 1
manuelpinto.in, 0
manuelrueger.de, 1
manufacturing.gov, 1
manuscript.com, 1
@ -21978,6 +21995,7 @@ mdek.at, 1
mdewendt.de, 1
mdf-bis.com, 1
mdiv.pl, 1
mdkr.nl, 1
mdlayher.com, 1
mdma.net, 1
mdmed.clinic, 1
@ -22968,7 +22986,6 @@ monolithindustries.com, 1
monolithinteractive.com, 1
monoseis-monotica.gr, 1
monothesis.com, 1
monotsuku.com, 1
monozukuri.cafe, 1
monpc-pro.fr, 1
monpermismoto.com, 1
@ -23164,7 +23181,7 @@ mplusm.eu, 1
mpn.poker, 1
mpnpokertour.com, 1
mpodraza.pl, 1
mpreserver.com, 0
mpreserver.com, 1
mprsco.eu, 1
mpserver12.org, 1
mpsgarage.com.au, 1
@ -23980,6 +23997,7 @@ ncconsumer.org, 1
ncdesigns-studio.com, 1
ncea.net.au, 1
nchangfong.com, 1
nchristo.com, 1
nclvle.co.uk, 1
ncrmnt.org, 1
ncsccs.com, 1
@ -24174,6 +24192,7 @@ netraising.com, 1
netrelay.email, 1
netrider.net.au, 0
netronix.be, 1
netsafeid.biz, 1
netscaler.expert, 1
netsight.org, 1
netsigna.de, 1
@ -25011,6 +25030,7 @@ officefundays.co.uk, 1
officeinteriors.co.nz, 1
officemovepro.com, 1
officeprint.co.th, 1
officiants.wedding, 0
officium.tech, 1
offroadeq.com, 1
offshoot.rentals, 1
@ -25417,7 +25437,6 @@ orangenbaum.at, 1
oranges.tokyo, 1
orangetravel.eu, 1
orangutan-appeal.org.uk, 1
oranic.com, 1
orbitdefence.co.uk, 1
orcahq.com, 1
orcamoney.com, 1
@ -26313,6 +26332,7 @@ peterhuetz.com, 1
peterjohnson.io, 1
peterlew.is, 1
petersontoscano.com, 1
pethelpers.org, 1
petit-archer.com, 1
petite-maison.ch, 1
petitsfrenchies.com, 1
@ -26446,6 +26466,7 @@ photon.sh, 1
photops.fr, 1
photosoftware.nl, 1
phototravel.uk, 1
phototrio.com, 1
phoxmeh.com, 1
php-developer.org, 1
php-tuning.de, 1
@ -27302,7 +27323,6 @@ primorus.lt, 1
primotilesandbathrooms.co.uk, 1
princeagency.com, 1
princeofwhales.com, 1
princesparktouch.com, 1
princessbackpack.de, 1
principalstest.com, 1
principaltoolbox.com, 1
@ -27619,8 +27639,6 @@ psychotherapie-kp.de, 1
psydix.org, 1
psyk.yt, 1
psylab.cc, 1
psylab.re, 1
psylab.vip, 1
psynapse.net.au, 1
psytrance-pro.com, 1
pt-server.de, 1
@ -28320,6 +28338,7 @@ redactieco.nl, 1
redb.cz, 1
redballoonsecurity.com, 1
redburn.com, 1
redcomet.org, 1
redcone.net, 1
redcorus.com, 1
redd.it, 1
@ -29256,7 +29275,6 @@ rullzer.com, 1
rulu.co, 1
rulu.tv, 1
rulutv.com, 1
rumlager.de, 1
rummel-platz.de, 1
rumplesinflatables.co.uk, 1
rumtaste.com, 1
@ -29375,7 +29393,6 @@ saabpartsdistribution.com, 1
saamhorigheidsfonds.nl, 0
saba-piserver.info, 1
sabahattin-gucukoglu.com, 1
sabatek.pl, 1
sabe.cz, 1
sabine-forschbach.de, 1
sabineforschbach.de, 1
@ -29914,6 +29931,7 @@ scootfleet.com, 1
scorobudem.ru, 1
scorocode.ru, 1
scorp13.com, 1
scotbirchfield.com, 1
scottainslie.me.uk, 1
scottgruber.me, 1
scottgthomas.com, 1
@ -29997,7 +30015,6 @@ seanationals.org, 1
seanchaidh.org, 1
seanholcroft.co.uk, 1
seankilgarriff.com, 1
seanstrout.com, 1
seaplayhomes.com, 1
search-job-in.com, 1
search-one.de, 1
@ -30098,7 +30115,6 @@ secure.facebook.com, 0
securedrop.org, 1
secureesolutions.com, 1
secureheaders.com, 1
secureideas.com, 0
secureim.de, 1
secureindia.co, 1
securejabber.me, 1
@ -30279,6 +30295,7 @@ seocomposer.com, 1
seoexperte.berlin, 1
seogeek.nl, 1
seohochschule.de, 1
seoinc.com, 1
seoium.com, 1
seokay.com, 1
seolib.org, 1
@ -31506,7 +31523,6 @@ solicafe.at, 1
solidimage.com.br, 1
solidshield.com, 1
solidtuesday.com, 1
solidwebnetworks.co.uk, 1
solihullcarnival.co.uk, 1
solihullinflatables.com, 1
solihulllionsclub.org.uk, 1
@ -32287,7 +32303,6 @@ stonewuu.com, 1
stony.com, 1
stonystratford.org, 1
stopakwardhandshakes.org, 1
stopbreakupnow.org, 1
stopbullying.gov, 1
stopfraud.gov, 1
stopthethyroidmadness.com, 1
@ -32533,6 +32548,7 @@ summercampthailand.com, 1
summershomes.com, 1
sumthing.com, 1
sun-leo.co.jp, 1
sun-wellness-online.com.vn, 1
sunboxstore.jp, 1
sunbritetv.com, 1
sunchasercats.com, 1
@ -32541,7 +32557,6 @@ sundayfundayjapan.com, 1
suneilpatel.com, 1
sunfeathers.net, 1
sunfireshop.com.br, 1
sunflyer.cn, 0
sunfox.cz, 1
sunfulong.blog, 1
sunfulong.me, 1
@ -32625,7 +32640,6 @@ suroil.com, 1
surpreem.com, 1
survature.com, 1
surveymill.co.uk, 1
survivalistplanet.com, 1
survivalmonkey.com, 1
survivebox.fr, 1
susanbpilates.co, 1
@ -33251,6 +33265,7 @@ teemperor.de, 1
teemulintula.fi, 1
teencounseling.com, 1
teenerotic.net, 1
teeplelaw.com, 1
teesypeesy.com, 1
teeworlds-friends.de, 1
tefek.cz, 1
@ -33520,6 +33535,7 @@ thebodyprinciple.com, 1
thebouncedepartment.co.uk, 1
thebouncyman.co.uk, 1
theboxofcarlos.com, 1
thebreakhotel.com, 1
thebreakroom.org, 1
thebte.com, 1
thebuffalotavern.com, 1
@ -33537,6 +33553,7 @@ thecloudshelter.com, 1
thecoffeepod.co.uk, 1
thecoffeesuperstore.com, 1
thecolumnist.net, 1
thecompany.pl, 1
theconcordbridge.azurewebsites.net, 1
thecondobuyers.com, 1
thecozycastle.com, 1
@ -33565,7 +33582,6 @@ thedominatorsclan.com, 1
thedreamtravelgroup.co.uk, 1
thedronechart.com, 1
thedrunkencabbage.com, 1
thedutchmarketers.com, 1
theebookkeepers.co.za, 1
theeducationchannel.info, 1
theeducationdirectory.org, 1
@ -34102,6 +34118,7 @@ tkn.tokyo, 1
tkts.cl, 1
tkusano.jp, 1
tkw01536.de, 0
tlach.cz, 1
tlca.org, 1
tlcnet.info, 1
tlehseasyads.com, 1
@ -35312,7 +35329,6 @@ unripple.com, 1
unruh.fr, 1
uns.vn, 1
unsacsurledos.com, 1
unschoolrules.com, 1
unsee.cc, 1
unseen.is, 1
unseen.tw, 1
@ -35805,7 +35821,6 @@ very-kids.fr, 1
veryapt.com, 1
verymelon.de, 1
veryyounglesbians.com, 0
verzekeringsacties.nl, 1
verzick.com, 1
ves.vn.ua, 1
vescudero.net, 1
@ -36170,7 +36185,7 @@ vorodevops.com, 1
vos-fleurs.ch, 1
vos-fleurs.com, 1
vosgym.jp, 1
voshod.org, 0
voshod.org, 1
vosjesweb.nl, 1
vosky.fr, 1
vosn.de, 1
@ -36719,7 +36734,6 @@ wellist.com, 1
wellmarts.com, 1
wellness-gutschein.de, 1
wellnesscheck.net, 1
wellopp.com, 1
wellsolveit.com, 1
wellsplasticsurgery.com, 1
wellspringcamps.com, 1
@ -37318,7 +37332,6 @@ wp6.pw, 1
wpac.de, 1
wpandup.org, 1
wpcdn.bid, 1
wpcharged.nz, 1
wpcheck.io, 1
wpdesigner.ir, 1
wpdirecto.com, 1
@ -37750,6 +37763,7 @@ xn--mein-kchenhelfer-ozb.de, 1
xn--mensenges-o1a8c.gq, 1
xn--mensengesss-t8a.gq, 1
xn--mentaltraining-fr-musiker-uwc.ch, 1
xn--mgbbh2a9fub.xn--ngbc5azd, 0
xn--mgbmmp7eub.com, 1
xn--mhsv04avtt1xi.com, 1
xn--mllers-wxa.info, 1
@ -37969,6 +37983,7 @@ ybscareers.co.uk, 1
ybsul.com, 1
ybti.net, 1
ybzhao.com, 1
ycaaz.com, 1
ych.art, 1
ycherbonnel.fr, 1
ychon.com, 1
@ -38367,7 +38382,6 @@ zargaripour.com, 1
zargescases.co.uk, 1
zarmarket.org, 1
zarpo.com.br, 1
zary.me, 1
zatsepin.by, 1
zaufanatrzeciastrona.pl, 1
zavec.com.ec, 1
@ -38473,7 +38487,6 @@ zhanghao.me, 1
zhangheda.cf, 1
zhangsir.net, 1
zhangyuhao.com, 1
zhangzifan.com, 1
zhaochen.xyz, 1
zhaofeng.li, 1
zhaoxixiangban.cc, 1

Просмотреть файл

@ -45,8 +45,16 @@ class VerifyToolsMixin(object):
for (path, suite) in manifests:
if os.path.exists(path):
man = TestManifest([path], strict=False)
active = man.active_tests(exists=False, disabled=False, filters=[], **mozinfo.info)
tests_by_path.update({t['relpath']:(suite,t.get('subsuite')) for t in active})
active = man.active_tests(exists=False, disabled=True, filters=[], **mozinfo.info)
# Remove disabled tests. Also, remove tests with the same path as
# disabled tests, even if they are not disabled, since test-verify
# specifies tests by path (it cannot distinguish between two or more
# tests with the same path specified in multiple manifests).
disabled = [t['relpath'] for t in active if 'disabled' in t]
new_by_path = {t['relpath']:(suite,t.get('subsuite')) \
for t in active if 'disabled' not in t and \
t['relpath'] not in disabled}
tests_by_path.update(new_by_path)
self.info("Verification updated with manifest %s" % path)
ref_manifests = [