| // 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); |
| }; |