mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 816730 - [Activities] Filters do not work anymore. r=mounir, sr=sicking
This commit is contained in:
parent
3c553a8b65
commit
11f00f17dc
@ -6,9 +6,12 @@ DEPTH = @DEPTH@
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = @relativesrcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
PARALLEL_DIRS = interfaces src
|
||||
|
||||
TEST_DIRS += tests
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -11,6 +11,7 @@ const Ci = Components.interfaces;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
|
||||
Cu.import("resource://gre/modules/ActivitiesServiceFilter.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
||||
"@mozilla.org/parentprocessmessagemanager;1",
|
||||
@ -258,39 +259,8 @@ let Activities = {
|
||||
};
|
||||
|
||||
let matchFunc = function matchFunc(aResult) {
|
||||
|
||||
function matchFuncValue(aValue, aFilter) {
|
||||
// Bug 805822 - Regexp support for MozActivity
|
||||
|
||||
let values = Array.isArray(aValue) ? aValue : [aValue];
|
||||
let filters = Array.isArray(aFilter) ? aFilter : [aFilter];
|
||||
|
||||
// At least 1 value must match.
|
||||
let ret = false;
|
||||
values.forEach(function(value) {
|
||||
if (filters.indexOf(value) != -1) {
|
||||
ret = true;
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// For any incoming property.
|
||||
for (let prop in aMsg.options.data) {
|
||||
|
||||
// If this is unknown for the app, let's continue.
|
||||
if (!(prop in aResult.description.filters)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, let's check the value against the filter.
|
||||
if (!matchFuncValue(aMsg.options.data[prop], aResult.description.filters[prop])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return ActivitiesServiceFilter.match(aMsg.options.data,
|
||||
aResult.description.filters);
|
||||
};
|
||||
|
||||
this.db.find(aMsg, successCb, errorCb, matchFunc);
|
||||
|
127
dom/activities/src/ActivitiesServiceFilter.jsm
Normal file
127
dom/activities/src/ActivitiesServiceFilter.jsm
Normal file
@ -0,0 +1,127 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict"
|
||||
|
||||
this.EXPORTED_SYMBOLS = ['ActivitiesServiceFilter'];
|
||||
|
||||
this.ActivitiesServiceFilter = {
|
||||
match: function(aValues, aFilters) {
|
||||
|
||||
function matchValue(aValue, aFilter, aFilterObj) {
|
||||
if (aFilter !== null) {
|
||||
// Custom functions for the different types.
|
||||
switch (typeof(aFilter)) {
|
||||
case 'boolean':
|
||||
return aValue === aFilter;
|
||||
|
||||
case 'number':
|
||||
return Number(aValue) === aFilter;
|
||||
|
||||
case 'string':
|
||||
return String(aValue) === aFilter;
|
||||
|
||||
default: // not supported
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Regexp.
|
||||
if (('regexp' in aFilterObj)) {
|
||||
var regexp = String(aFilterObj.regexp);
|
||||
|
||||
if (regexp[0] != "/")
|
||||
return false;
|
||||
|
||||
var pos = regexp.lastIndexOf("/");
|
||||
if (pos == 0)
|
||||
return false;
|
||||
|
||||
var re = new RegExp(regexp.substring(1, pos), regexp.substr(pos + 1));
|
||||
return re.test(aValue);
|
||||
}
|
||||
|
||||
// Validation of the min/Max.
|
||||
if (('min' in aFilterObj) || ('max' in aFilterObj)) {
|
||||
// Min value.
|
||||
if (('min' in aFilterObj) &&
|
||||
aFilterObj.min > aValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Max value.
|
||||
if (('max' in aFilterObj) &&
|
||||
aFilterObj.max < aValue) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// this function returns true if the value matches with the filter object
|
||||
function matchObject(aValue, aFilterObj) {
|
||||
|
||||
// Let's consider anything an array.
|
||||
let filters = ('value' in aFilterObj)
|
||||
? (Array.isArray(aFilterObj.value)
|
||||
? aFilterObj.value
|
||||
: [aFilterObj.value])
|
||||
: [ null ];
|
||||
let values = Array.isArray(aValue) ? aValue : [aValue];
|
||||
|
||||
for (var filterId = 0; filterId < filters.length; ++filterId) {
|
||||
for (var valueId = 0; valueId < values.length; ++valueId) {
|
||||
if (matchValue(values[valueId], filters[filterId], aFilterObj)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Creation of a filter map useful to know what has been
|
||||
// matched and what is not.
|
||||
let filtersMap = {}
|
||||
for (let filter in aFilters) {
|
||||
// Convert this filter in an object if needed
|
||||
let filterObj = aFilters[filter];
|
||||
|
||||
if (Array.isArray(filterObj) || typeof(filterObj) !== 'object') {
|
||||
filterObj = {
|
||||
required: false,
|
||||
value: filterObj
|
||||
}
|
||||
}
|
||||
|
||||
filtersMap[filter] = { filter: filterObj,
|
||||
found: false };
|
||||
}
|
||||
|
||||
// For any incoming property.
|
||||
for (let prop in aValues) {
|
||||
// If this is unknown for the app, let's continue.
|
||||
if (!(prop in filtersMap)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, let's check the value against the filter.
|
||||
if (!matchObject(aValues[prop], filtersMap[prop].filter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
filtersMap[prop].found = true;
|
||||
}
|
||||
|
||||
// Required filters:
|
||||
for (let filter in filtersMap) {
|
||||
if (filtersMap[filter].filter.required && !filtersMap[filter].found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -36,6 +36,7 @@ EXTRA_COMPONENTS = \
|
||||
|
||||
EXTRA_JS_MODULES = \
|
||||
ActivitiesService.jsm \
|
||||
ActivitiesServiceFilter.jsm \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
17
dom/activities/tests/Makefile.in
Normal file
17
dom/activities/tests/Makefile.in
Normal file
@ -0,0 +1,17 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEPTH = @DEPTH@
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = @relativesrcdir@
|
||||
|
||||
FAIL_ON_WARNINGS := 1
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
XPCSHELL_TESTS = unit
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
151
dom/activities/tests/unit/test_activityFilters.js
Normal file
151
dom/activities/tests/unit/test_activityFilters.js
Normal file
@ -0,0 +1,151 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function run_test() {
|
||||
Components.utils.import("resource:///modules/ActivitiesServiceFilter.jsm")
|
||||
|
||||
do_check_true(!!ActivitiesServiceFilter);
|
||||
|
||||
// No requests, no filters:
|
||||
do_check_true(ActivitiesServiceFilter.match(null, null));
|
||||
do_check_true(ActivitiesServiceFilter.match({}, {}));
|
||||
|
||||
// No filters:
|
||||
do_check_true(ActivitiesServiceFilter.match({foobar: 42}, null));
|
||||
|
||||
// Empty request:
|
||||
do_check_true(ActivitiesServiceFilter.match({}, {a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
|
||||
|
||||
// Simple match:
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 'foobar'},
|
||||
{a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 'foobar', b: 2, c: true},
|
||||
{a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 'foobar', b: 2, c: 42},
|
||||
{a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 'foobar2'},
|
||||
{a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
|
||||
// Simple match in array:
|
||||
do_check_true(ActivitiesServiceFilter.match({b: 2},
|
||||
{a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
do_check_false(ActivitiesServiceFilter.match({b: 4},
|
||||
{a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
do_check_true(ActivitiesServiceFilter.match({b: [2, 4]},
|
||||
{a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
do_check_false(ActivitiesServiceFilter.match({b: [4, 5]},
|
||||
{a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: [4, 'foobar2']},
|
||||
{a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: [4, 'foobar']},
|
||||
{a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: ['foo', 'bar']},
|
||||
{a: 'foo'}));
|
||||
|
||||
// Unknown property
|
||||
do_check_true(ActivitiesServiceFilter.match({k: 4},
|
||||
{a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
do_check_true(ActivitiesServiceFilter.match({k: [1,2,3,4]},
|
||||
{a: 'foobar', b: [1, 2, 3], c: 42}));
|
||||
|
||||
// Required/non required
|
||||
do_check_false(ActivitiesServiceFilter.match({},
|
||||
{a: { required: true, value: 'foobar'}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 'foobar'},
|
||||
{a: { required: true, value: 'foobar'}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 'foobar2'},
|
||||
{a: { required: true, value: 'foobar'}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 'foobar2'},
|
||||
{a: { required: true, value: ['a', 'b', 'foobar']}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 'foobar'},
|
||||
{a: { required: true, value: ['a', 'b', 'foobar']}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: ['k', 'z', 'foobar']},
|
||||
{a: { required: true, value: ['a', 'b', 'foobar']}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: ['k', 'z', 'foobar2']},
|
||||
{a: { required: true, value: ['a', 'b', 'foobar']}}));
|
||||
|
||||
// Empty values
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 42},
|
||||
{a: { required: true}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({},
|
||||
{a: { required: true}}));
|
||||
|
||||
// Boolean
|
||||
do_check_true(ActivitiesServiceFilter.match({a: false},
|
||||
{a: { required: true, value: false}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: true},
|
||||
{a: { required: true, value: false}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: [false, true]},
|
||||
{a: { required: true, value: false}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: [false, true]},
|
||||
{a: { required: true, value: [false,true]}}));
|
||||
|
||||
// Number
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 42},
|
||||
{a: { required: true, value: 42}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, value: 42}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, min: 1}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, min: 2}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, min: 3}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, max: 1}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, max: 2}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, max: 3}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, min: 1, max: 1}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, min: 1, max: 2}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, min: 2, max: 2}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, value: 'foo'}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, min: 100, max: 0}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, min: 'a', max: 'b'}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 2},
|
||||
{a: { required: true, min: 10, max: 1}}));
|
||||
|
||||
// String
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 'foo'},
|
||||
{a: { required: true, value: 'foo'}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 'foo2'},
|
||||
{a: { required: true, value: 'foo'}}));
|
||||
|
||||
// Number VS string
|
||||
do_check_true(ActivitiesServiceFilter.match({a: '42'},
|
||||
{a: { required: true, value: 42}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 42},
|
||||
{a: { required: true, value: '42'}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: '-42e+12'},
|
||||
{a: { required: true, value: -42e+12}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 42},
|
||||
{a: { required: true, min: '1', max: '50'}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: '42'},
|
||||
{a: 42 }));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 42},
|
||||
{a: '42' }));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 42},
|
||||
{a: { min: '44' }}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 42},
|
||||
{a: { max: '0' }}));
|
||||
|
||||
// String + RegExp
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 'foobar'},
|
||||
{a: { required: true, regexp: '/^foobar/'}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 'aafoobar'},
|
||||
{a: { required: true, regexp: '/^foobar/'}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 'aaFOOsdsad'},
|
||||
{a: { required: true, regexp: '/foo/i'}}));
|
||||
do_check_true(ActivitiesServiceFilter.match({a: 'aafoobarasdsad'},
|
||||
{a: { required: true, regexp: '/foo/'}}));
|
||||
do_check_false(ActivitiesServiceFilter.match({a: 'aaFOOsdsad'},
|
||||
{a: { required: true, regexp: '/foo/'}}));
|
||||
}
|
5
dom/activities/tests/unit/xpcshell.ini
Normal file
5
dom/activities/tests/unit/xpcshell.ini
Normal file
@ -0,0 +1,5 @@
|
||||
[DEFAULT]
|
||||
head =
|
||||
tail =
|
||||
|
||||
[test_activityFilters.js]
|
@ -9,6 +9,7 @@
|
||||
[include:uriloader/exthandler/tests/unit/xpcshell.ini]
|
||||
[include:parser/xml/test/unit/xpcshell.ini]
|
||||
[include:image/test/unit/xpcshell.ini]
|
||||
[include:dom/activities/tests/unit/xpcshell.ini]
|
||||
[include:dom/encoding/test/unit/xpcshell.ini]
|
||||
[include:dom/plugins/test/unit/xpcshell.ini]
|
||||
[include:dom/sms/tests/xpcshell.ini]
|
||||
|
Loading…
Reference in New Issue
Block a user