blob: c8acab4998aab27e2c325a439abb969905236bd5 [file] [log] [blame]
// The sample API integrates origin trial checks at various entry points.
// References to "partial interface" mean that the [OriginTrialEnabled]
// IDL attribute is applied to an entire partial interface, instead of
// applied to individual IDL members.
// Verify that the given member exists, and returns an actual value
// (i.e. not undefined).
expect_member = (member_name, get_value_func) => {
var testObject = internals.originTrialsTest();
assert_idl_attribute(testObject, member_name);
assert_true(get_value_func(testObject),
'Member should return boolean value');
}
// Verify that the given member exists on the returned dictionary, and returns
// an actual value (i.e. not undefined).
expect_dictionary_member = (dictionary_member_name) => {
var testObject = internals.originTrialsTest();
var dictionary = testObject.getDictionaryMethod();
assert_own_property(dictionary, dictionary_member_name);
assert_true(dictionary[dictionary_member_name],
'Dictionary member ' + dictionary_member_name + ' should return boolean value');
}
// Verify that the given member is accessed as part of dictionary input to a
// method
expect_input_dictionary_member = (dictionary_member_name) => {
var testObject = internals.originTrialsTest();
// Test via a getter in the object to see if the member is accessed
var memberAccessed = false;
try {
var dictionary = Object.defineProperty({}, dictionary_member_name, {
get: function() {
memberAccessed = true;
}
});
testObject.checkDictionaryMethod(dictionary);
} catch (e) {}
assert_true(memberAccessed,
'Dictionary member ' + dictionary_member_name + ' should be accessed by method');
}
// Verify that the given static member exists, and returns an actual value
// (i.e. not undefined).
expect_static_member = (member_name, get_value_func) => {
var testObject = internals.originTrialsTest();
var testInterface = testObject.constructor;
assert_own_property(testInterface, member_name);
assert_true(get_value_func(testInterface),
'Static member should return boolean value');
}
// Verify that the given constant exists, and returns the expected value, and
// is not modifiable.
expect_constant = (constant_name, constant_value, get_value_func) => {
var testObject = internals.originTrialsTest();
var testInterface = testObject.constructor;
assert_own_property(testInterface, constant_name);
assert_equals(get_value_func(testInterface), constant_value,
'Constant should return expected value');
testInterface[constant_name] = constant_value + 1;
assert_equals(get_value_func(testInterface), constant_value,
'Constant should not be modifiable');
}
// Verify that given member does not exist, and does not provide a value
// (i.e. is undefined).
expect_member_fails = (member_name) => {
var testObject = internals.originTrialsTest();
assert_false(member_name in testObject);
assert_equals(testObject[member_name], undefined);
}
// Verify that the given member does not exist on the returned dictionary, and
// does not provide a value (i.e. is undefined).
expect_dictionary_member_fails = (dictionary_member_name) => {
var testObject = internals.originTrialsTest();
var dictionary = testObject.getDictionaryMethod();
assert_false(dictionary_member_name in dictionary);
assert_equals(dictionary[dictionary_member_name], undefined,
'Dictionary member ' + dictionary_member_name + ' should not have a value');
}
// Verify that the given member is not accessed as part of dictionary input to a
// method
expect_input_dictionary_member_fails = (dictionary_member_name) => {
var testObject = internals.originTrialsTest();
// Test via a getter in the object to see if the member is accessed
var memberAccessed = false;
try {
var dictionary = Object.defineProperty({}, dictionary_member_name, {
get: function() {
memberAccessed = true;
}
});
testObject.checkDictionaryMethod(dictionary);
} catch (e) {}
assert_false(memberAccessed,
'Dictionary member ' + dictionary_member_name + ' should not be accessed by method');
}
// Verify that given static member does not exist, and does not provide a value
// (i.e. is undefined).
expect_static_member_fails = (member_name) => {
var testObject = internals.originTrialsTest();
var testInterface = testObject.constructor;
assert_false(member_name in testInterface);
assert_equals(testInterface[member_name], undefined);
}
// These tests verify that any gated parts of the API are not available.
expect_failure = (skip_worker) => {
test(() => {
var testObject = internals.originTrialsTest();
assert_idl_attribute(testObject, 'throwingAttribute');
assert_throws("NotSupportedError", () => { testObject.throwingAttribute; },
'Accessing attribute should throw error');
}, 'Accessing attribute should throw error');
test(() => {
expect_member_fails('normalAttribute');
}, 'Attribute should not exist, with trial disabled');
test(() => {
expect_static_member_fails('CONSTANT');
}, 'Constant should not exist, with trial disabled');
if (!skip_worker) {
fetch_tests_from_worker(new Worker('resources/disabled-worker.js'));
}
};
// These tests verify that any gated parts of the API are not available for an
// implied trial.
expect_failure_implied = (skip_worker) => {
test(() => {
expect_member_fails('impliedAttribute');
}, 'Implied attribute should not exist, with trial disabled');
if (!skip_worker) {
fetch_tests_from_worker(new Worker('resources/implied-disabled-worker.js'));
}
};
// These tests verify that the API functions correctly with an enabled trial.
expect_success = () => {
test(() => {
expect_member('throwingAttribute', (testObject) => {
return testObject.throwingAttribute;
});
}, 'Accessing attribute should return value and not throw exception');
test(() => {
expect_member('normalAttribute', (testObject) => {
return testObject.normalAttribute;
});
}, 'Attribute should exist on object and return value');
test(() => {
expect_constant('CONSTANT', 1, (testObject) => {
return testObject.CONSTANT;
});
}, 'Constant should exist on interface and return value');
fetch_tests_from_worker(new Worker('resources/enabled-worker.js'));
};
// These tests verify that the API functions correctly with an implied trial
// that is enabled.
expect_success_implied = (opt_description_suffix, skip_worker) => {
var description_suffix = opt_description_suffix || '';
test(() => {
expect_member('impliedAttribute', (testObject) => {
return testObject.impliedAttribute;
});
}, 'Implied attribute should exist on object and return value' + description_suffix);
if (!skip_worker) {
fetch_tests_from_worker(new Worker('resources/implied-enabled-worker.js'));
}
};
// These tests should pass, regardless of the state of the trial. These are
// control tests for IDL members without the [OriginTrialEnabled] extended
// attribute. The control tests will vary for secure vs insecure context.
expect_always_bindings = (insecure_context, opt_description_suffix) => {
var description_suffix = opt_description_suffix || '';
test(() => {
assert_idl_attribute(window.internals, 'originTrialsTest');
}, 'Test object should exist on window.internals, regardless of trial' + description_suffix);
test(() => {
expect_member('unconditionalAttribute', (testObject) => {
return testObject.unconditionalAttribute;
});
}, 'Attribute should exist and return value, regardless of trial' + description_suffix);
test(() => {
expect_static_member('staticUnconditionalAttribute', (testObject) => {
return testObject.staticUnconditionalAttribute;
});
}, 'Static attribute should exist and return value, regardless of trial' + description_suffix);
test(() => {
expect_member('unconditionalMethod', (testObject) => {
return testObject.unconditionalMethod();
});
}, 'Method should exist and return value, regardless of trial' + description_suffix);
test(() => {
expect_static_member('staticUnconditionalMethod', (testObject) => {
return testObject.staticUnconditionalMethod();
});
}, 'Static method should exist and return value, regardless of trial' + description_suffix);
test(() => {
expect_constant('UNCONDITIONAL_CONSTANT', 99, (testObject) => {
return testObject.UNCONDITIONAL_CONSTANT;
});
}, 'Constant should exist on interface and return value, regardless of trial' + description_suffix);
test(() => {
expect_dictionary_member('unconditionalBool');
}, 'Dictionary output from method should return member value, regardless of trial' + description_suffix);
test(() => {
expect_input_dictionary_member('unconditionalBool');
}, 'Method with input dictionary should access member value, regardless of trial' + description_suffix);
if (insecure_context) {
test(() => {
expect_member_fails('secureUnconditionalAttribute');
}, 'Secure attribute should not exist, regardless of trial' + description_suffix);
test(() => {
expect_member_fails('secureStaticUnconditionalAttribute');
}, 'Secure static attribute should not exist, regardless of trial' + description_suffix);
test(() => {
expect_member_fails('secureUnconditionalMethod');
}, 'Secure method should not exist, regardless of trial' + description_suffix);
test(() => {
expect_member_fails('secureStaticUnconditionalMethod');
}, 'Secure static method should not exist, regardless of trial' + description_suffix);
} else {
test(() => {
expect_member('secureUnconditionalAttribute', (testObject) => {
return testObject.secureUnconditionalAttribute;
});
}, 'Secure attribute should exist and return value, regardless of trial' + description_suffix);
test(() => {
expect_static_member('secureStaticUnconditionalAttribute', (testObject) => {
return testObject.secureStaticUnconditionalAttribute;
});
}, 'Secure static attribute should exist and return value, regardless of trial' + description_suffix);
test(() => {
expect_member('secureUnconditionalMethod', (testObject) => {
return testObject.secureUnconditionalMethod();
});
}, 'Secure method should exist and return value, regardless of trial' + description_suffix);
test(() => {
expect_static_member('secureStaticUnconditionalMethod', (testObject) => {
return testObject.secureStaticUnconditionalMethod();
});
}, 'Secure static method should exist and return value, regardless of trial' + description_suffix);
}
};
// Verify that all IDL members are correctly exposed with an enabled trial.
expect_success_bindings = (insecure_context) => {
expect_always_bindings(insecure_context);
if (insecure_context) {
// Origin trials only work in secure contexts, so tests cannot distinguish
// between [OriginTrialEnabled] or [SecureContext] preventing exposure of
// IDL members. These tests at least ensure IDL members are not exposed in
// insecure contexts, regardless of reason.
test(() => {
expect_member_fails('secureAttribute');
}, 'Secure attribute should not exist');
test(() => {
expect_static_member_fails('secureStaticAttribute');
}, 'Secure static attribute should not exist');
test(() => {
expect_member_fails('secureMethod');
}, 'Secure method should not exist');
test(() => {
expect_static_member_fails('secureStaticMethod');
}, 'Secure static method should not exist');
test(() => {
expect_member_fails('secureAttributePartial');
}, 'Secure attribute should not exist on partial interface');
test(() => {
expect_static_member_fails('secureStaticAttributePartial');
}, 'Secure static attribute should not exist on partial interface');
test(() => {
expect_member_fails('secureMethodPartial');
}, 'Secure method should not exist on partial interface');
test(() => {
expect_static_member_fails('secureStaticMethodPartial');
}, 'Secure static method should not exist on partial interface');
return;
}
test(() => {
expect_member('normalAttribute', (testObject) => {
return testObject.normalAttribute;
});
}, 'Attribute should exist and return value');
test(() => {
expect_static_member('staticAttribute', (testObject) => {
return testObject.staticAttribute;
});
}, 'Static attribute should exist and return value');
test(() => {
expect_member('normalMethod', (testObject) => {
return testObject.normalMethod();
});
}, 'Method should exist and return value');
test(() => {
expect_static_member('staticMethod', (testObject) => {
return testObject.staticMethod();
});
}, 'Static method should exist and return value');
test(() => {
expect_dictionary_member('normalBool');
}, 'Dictionary output from method should return member value');
test(() => {
expect_input_dictionary_member('normalBool');
}, 'Method with input dictionary should access member value');
// Tests for [OriginTrialEnabled] on partial interfaces
test(() => {
expect_member('normalAttributePartial', (testObject) => {
return testObject.normalAttributePartial;
});
}, 'Attribute should exist on partial interface and return value');
test(() => {
expect_static_member('staticAttributePartial', (testObject) => {
return testObject.staticAttributePartial;
});
}, 'Static attribute should exist on partial interface and return value');
test(() => {
expect_member('normalMethodPartial', (testObject) => {
return testObject.normalMethodPartial();
});
}, 'Method should exist on partial interface and return value');
test(() => {
expect_static_member('staticMethodPartial', (testObject) => {
return testObject.staticMethodPartial();
});
}, 'Static method should exist on partial interface and return value');
test(() => {
expect_constant('CONSTANT_PARTIAL', 2, (testObject) => {
return testObject.CONSTANT_PARTIAL;
});
}, 'Constant should exist on partial interface and return value');
// Tests for combination of [OriginTrialEnabled] and [SecureContext]
test(() => {
expect_member('secureAttribute', (testObject) => {
return testObject.secureAttribute;
});
}, 'Secure attribute should exist and return value');
test(() => {
expect_static_member('secureStaticAttribute', (testObject) => {
return testObject.secureStaticAttribute;
});
}, 'Secure static attribute should exist and return value');
test(() => {
expect_member('secureMethod', (testObject) => {
return testObject.secureMethod();
});
}, 'Secure method should exist and return value');
test(() => {
expect_static_member('secureStaticMethod', (testObject) => {
return testObject.secureStaticMethod();
});
}, 'Secure static method should exist and return value');
test(() => {
expect_member('secureAttributePartial', (testObject) => {
return testObject.secureAttributePartial;
});
}, 'Secure attribute should exist on partial interface and return value');
test(() => {
expect_static_member('secureStaticAttributePartial', (testObject) => {
return testObject.secureStaticAttributePartial;
});
}, 'Secure static attribute should exist on partial interface and return value');
test(() => {
expect_member('secureMethodPartial', (testObject) => {
return testObject.secureMethodPartial();
});
}, 'Secure method should exist on partial interface and return value');
test(() => {
expect_static_member('secureStaticMethodPartial', (testObject) => {
return testObject.secureStaticMethodPartial();
});
}, 'Secure static method should exist on partial interface and return value');
};
// Verify that all IDL members are correctly exposed with an enabled trial, with
// an insecure context.
expect_success_bindings_insecure_context = () => {
expect_success_bindings(true);
};
// Verify that all IDL members are not exposed with a disabled trial.
expect_failure_bindings_impl = (insecure_context, description_suffix) => {
expect_always_bindings(insecure_context, description_suffix);
test(() => {
expect_member_fails('normalMethod');
}, 'Method should not exist, with trial disabled');
test(() => {
expect_static_member_fails('staticMethod');
}, 'Static method should not exist, with trial disabled');
test(() => {
expect_dictionary_member_fails('normalBool');
}, 'Dictionary output from method should not return member value, with trial disabled');
test(() => {
expect_input_dictionary_member_fails('normalBool');
}, 'Method with input dictionary should not access member value, with trial disabled');
// Tests for combination of [OriginTrialEnabled] and [SecureContext]
if (insecure_context) {
// Origin trials only work in secure contexts, so tests cannot distinguish
// between [OriginTrialEnabled] or [SecureContext] preventing exposure of
// IDL members. There are tests to ensure IDL members are not exposed in
// insecure contexts in expect_success_bindings().
return;
}
// Tests for [OriginTrialEnabled] on partial interfaces
test(() => {
expect_member_fails('normalAttributePartial');
}, 'Attribute should not exist on partial interface, with trial disabled');
test(() => {
expect_static_member_fails('staticAttributePartial');
}, 'Static attribute should not exist on partial interface, with trial disabled');
test(() => {
expect_member_fails('methodPartial');
}, 'Method should not exist on partial interface, with trial disabled');
test(() => {
expect_static_member_fails('staticMethodPartial');
}, 'Static method should not exist on partial interface, with trial disabled');
test(() => {
expect_static_member_fails('CONSTANT_PARTIAL');
}, 'Constant should not exist on partial interface, with trial disabled');
// Tests for combination of [OriginTrialEnabled] and [SecureContext]
test(() => {
expect_member_fails('secureAttribute');
}, 'Secure attribute should not exist, with trial disabled');
test(() => {
expect_static_member_fails('secureStaticAttribute');
}, 'Secure static attribute should not exist, with trial disabled');
test(() => {
expect_member_fails('secureMethod');
}, 'Secure method should not exist, with trial disabled');
test(() => {
expect_static_member_fails('secureStaticMethod');
}, 'Secure static method should not exist, with trial disabled');
test(() => {
expect_member_fails('secureAttributePartial');
}, 'Secure attribute should not exist on partial interface, with trial disabled');
test(() => {
expect_static_member_fails('secureStaticAttributePartial');
}, 'Secure static attribute should not exist on partial interface, with trial disabled');
test(() => {
expect_member_fails('secureMethodPartial');
}, 'Secure method should not exist on partial interface, with trial disabled');
test(() => {
expect_static_member_fails('secureStaticMethodPartial');
}, 'Secure static method should not exist on partial interface, with trial disabled');
};
// Verify that all IDL members are not exposed with a disabled trial.
// Assumes a secure context.
expect_failure_bindings = (description_suffix) => {
expect_failure_bindings_impl(false, description_suffix);
};
// Verify that all IDL members are not exposed with a disabled trial, with an
// insecure context
expect_failure_bindings_insecure_context = (description_suffix) => {
expect_failure_bindings_impl(true, description_suffix);
};