// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
GEN_INCLUDE(['cvd_type.js', 'storage.js']);
GEN_INCLUDE([
'../../webstore_extension_test_base.js',
'//chrome/browser/resources/chromeos/accessibility/common/testing/' +
'callback_helper.js',
'//chrome/browser/resources/chromeos/accessibility/common/testing/' +
'mock_storage.js',
]);
/** Test fixture for storage.js. */
ColorEnhancerStorageTest = class extends WebstoreExtensionTest {
/** @override */
setUp() {
this.callbackHelper_ = new CallbackHelper(this);
chrome.storage = MockStorage;
Storage.initialize();
}
/**
* Increments a counter, to wait for all callbacks to be completed before
* finishing the test.
* @param {Function=} opt_callback
* @return {Function}
*/
newCallback(opt_callback) {
return this.callbackHelper_.wrap(opt_callback);
}
};
/**
* @param {number} expected
* @param {number} actual
*/
function checkFloatValue(expected, actual) {
const difference = Math.abs(expected - actual);
assertLE(difference, 0.01, 'Floating point number is not the expected value');
}
TEST_F('ColorEnhancerStorageTest', 'DefaultValues', function() {
checkFloatValue(0.5, Storage.baseDelta);
checkFloatValue(0.5, Storage.getSiteDelta('default.com'));
checkFloatValue(1.0, Storage.severity);
assertEquals(Storage.INVALID_TYPE_PLACEHOLDER, Storage.type);
assertEquals(CvdAxis.DEFAULT, Storage.axis);
assertEquals(false, Storage.simulate);
assertEquals(false, Storage.enable);
});
TEST_F('ColorEnhancerStorageTest', 'SetValues', function() {
// Default delta
Storage.baseDelta = 0.8;
checkFloatValue(0.8, Storage.baseDelta);
let storedValue = MockStorage.local_[Storage.DELTA.key];
assertEquals('number', typeof (storedValue));
checkFloatValue(0.8, storedValue);
// Check that unset sites fall back to the default delta.
checkFloatValue(0.8, Storage.getSiteDelta('unset.com'));
// Severity
Storage.severity = 0.2;
checkFloatValue(0.2, Storage.severity);
storedValue = MockStorage.local_[Storage.SEVERITY.key];
assertEquals('number', typeof (storedValue));
checkFloatValue(0.2, storedValue);
// Type
Storage.type = CvdType.PROTANOMALY;
assertEquals(CvdType.PROTANOMALY, Storage.type);
storedValue = MockStorage.local_[Storage.TYPE.key];
assertEquals('string', typeof (storedValue));
assertEquals(CvdType.PROTANOMALY, storedValue);
// Axis
Storage.axis = CvdAxis.RED;
assertEquals(CvdAxis.RED, Storage.axis);
storedValue = MockStorage.local_[Storage.AXIS.key];
assertEquals('string', typeof (storedValue));
assertEquals(CvdAxis.RED, storedValue);
// Simulate
Storage.simulate = true;
assertEquals(true, Storage.simulate);
storedValue = MockStorage.local_[Storage.SIMULATE.key];
assertEquals('boolean', typeof (storedValue));
assertEquals(true, storedValue);
// Enable
Storage.enable = true;
assertEquals(true, Storage.enable);
storedValue = MockStorage.local_[Storage.ENABLE.key];
assertEquals('boolean', typeof (storedValue));
assertEquals(true, storedValue);
// Site delta
Storage.setSiteDelta('set.com', 0.9);
checkFloatValue(0.9, Storage.getSiteDelta('set.com'));
storedValue = MockStorage.local_[Storage.SITE_DELTAS.key];
assertEquals('object', typeof (storedValue));
assertEquals('number', typeof (storedValue['set.com']));
checkFloatValue(0.9, storedValue['set.com']);
});
TEST_F('ColorEnhancerStorageTest', 'SetInvalidValues', function() {
// Default delta
Storage.baseDelta = 1.8; // Delta must be between 0 and 1.
checkFloatValue(0.5, Storage.baseDelta);
let storedValue = MockStorage.local_[Storage.DELTA.key];
assertEquals('number', typeof (storedValue));
checkFloatValue(0.5, storedValue);
// Severity
Storage.severity = 2; // Severity must be between 0 and 1.
checkFloatValue(1.0, Storage.severity);
storedValue = MockStorage.local_[Storage.SEVERITY.key];
assertEquals('number', typeof (storedValue));
checkFloatValue(1.0, storedValue);
// Type
Storage.type = 'something else'; // Type must be a CvdType.
assertEquals(Storage.INVALID_TYPE_PLACEHOLDER, Storage.type);
storedValue = MockStorage.local_[Storage.TYPE.key];
assertEquals(Storage.INVALID_TYPE_PLACEHOLDER, storedValue);
// Axis
Storage.axis = 'PURPLE'; // Axis must be a CvdAxis.
assertEquals(CvdAxis.DEFAULT, Storage.axis);
storedValue = MockStorage.local_[Storage.AXIS.key];
assertEquals(CvdAxis.DEFAULT, storedValue);
// Simulate
Storage.simulate = 7; // Simulate must be a boolean.
assertEquals(false, Storage.simulate);
storedValue = MockStorage.local_[Storage.SIMULATE.key];
assertEquals('boolean', typeof (storedValue));
assertEquals(false, storedValue);
// Enable
Storage.enable = 'x'; // Enable must be a boolean
assertEquals(false, Storage.enable);
storedValue = MockStorage.local_[Storage.ENABLE.key];
assertEquals('boolean', typeof (storedValue));
assertEquals(false, storedValue);
// Site delta
Storage.setSiteDelta('invalid.com', 9.9);
checkFloatValue(0.5, Storage.getSiteDelta('invalid.com'));
storedValue = MockStorage.local_[Storage.SITE_DELTAS.key];
assertEquals('object', typeof (storedValue));
assertEquals('number', typeof (storedValue['invalid.com']));
checkFloatValue(0.5, storedValue['invalid.com']);
});
TEST_F('ColorEnhancerStorageTest', 'Listeners', function() {
Storage.DELTA.listeners.push(this.newCallback(newVal => {
checkFloatValue(0.8, newVal);
Storage.DELTA.listeners.pop();
}));
Storage.baseDelta = 0.8;
// When an invalid value is provided, Storage resets to the default, and
// listeners are called.
Storage.SEVERITY.listeners.push(this.newCallback(newVal => {
checkFloatValue(0.5, newVal);
Storage.SEVERITY.listeners.pop();
}));
Storage.severity = 7.2;
Storage.TYPE.listeners.push(this.newCallback(newVal => {
assertEquals(CvdType.PROTANOMLAY, newVal);
Storage.TYPE.listeners.pop();
}));
Storage.type = CvdType.PROTANOMALY;
Storage.AXIS.listeners.push(this.newCallback(newVal => {
assertEquals(CvdAxis.RED, newVal);
Storage.AXIS.listeners.pop();
}));
Storage.type = CvdAxis.RED;
Storage.SIMULATE.listeners.push(
this.newCallback(newVal => assertEquals(true, newVal)));
Storage.simulate = true;
// Setting to the same value already set should not call the listener.
Storage.simulate = true;
// Clean up the listener. Note: if callback is async in testing, you'll need
// to find another place for this.
Storage.SIMULATE.listeners.pop();
Storage.ENABLE.listeners.push(this.newCallback(newVal => {
assertEquals(true, newVal);
Storage.ENABLE.listeners.pop();
}));
Storage.enable = true;
Storage.SITE_DELTAS.listeners.push(this.newCallback(newVal => {
assertEquals('object', typeof (newVal));
assertEquals('number', typeof (newVal['listener.com']));
checkFloatValue(0.1, newVal['listener.com']);
Storage.SITE_DELTAS.listeners.pop();
}));
Storage.setSiteDelta('listener.com', 0.1);
});
TEST_F('ColorEnhancerStorageTest', 'InitialFetch', function() {
// Make sure any values from previous tests are cleared.
MockStorage.local_ = {};
Storage.baseDelta = 0.7;
Storage.type = CvdType.PROTANOMALY;
Storage.enable = true;
Storage.setSiteDelta('fetch.com', 0.2);
// Simulate re-starting the extension by creating a new instance.
Storage.initialize(this.newCallback(() => {
checkFloatValue(0.7, Storage.baseDelta);
assertEquals(CvdType.PROTANOMALY, Storage.type);
assertEquals(true, Storage.enable);
checkFloatValue(0.2, Storage.getSiteDelta('fetch.com'));
// Check that unset values are at default.
checkFloatValue(1.0, Storage.severity);
assertEquals(false, Storage.simulate);
assertEquals(CvdAxis.DEFAULT, Storage.axis);
}));
});
TEST_F('ColorEnhancerStorageTest', 'LegacyFetch', function() {
// Make sure any values from previous tests are cleared.
MockStorage.local_ = {};
Storage.baseDelta = 0.7;
Storage.type = CvdType.DEUTERANOMALY;
Storage.enable = true;
Storage.setSiteDelta('fetch.com', 0.2);
delete MockStorage.local_[Storage.AXIS.key]
// Simulate re-starting the extension by creating a new instance.
Storage.initialize(this.newCallback(() => {
checkFloatValue(0.7, Storage.baseDelta);
assertEquals(CvdType.DEUTERANOMALY, Storage.type);
assertEquals(true, Storage.enable);
checkFloatValue(0.2, Storage.getSiteDelta('fetch.com'));
// Check that Axis uses legacy value
assertEquals(CvdAxis.RED, Storage.axis);
}));
});
TEST_F('ColorEnhancerStorageTest', 'OnChange', function() {
Storage.SEVERITY.listeners.push(this.newCallback((newVal) => {
assertEquals(0.35, newVal);
Storage.SEVERITY.listeners.pop();
}));
// Because the listener is only called if the value changes, make sure the
// value is false beforehand.
Storage.simulate = false;
Storage.SIMULATE.listeners.push(this.newCallback((newVal) => {
assertEquals(true, newVal);
Storage.SIMULATE.listeners.pop();
}));
Storage.AXIS.listeners.push(this.newCallback((newVal) => {
assertEquals(CvdAxis.RED, newVal);
Storage.AXIS.listeners.pop();
}));
MockStorage.callOnChangedListeners({
[Storage.SEVERITY.key]: 0.35,
[Storage.SIMULATE.key]: true,
[Storage.AXIS.key]: CvdAxis.RED,
});
// Check that the values were set properly, in addition to the callbacks being
// called.
checkFloatValue(0.35, Storage.severity);
assertEquals(true, Storage.simulate);
assertEquals(CvdAxis.RED, Storage.axis);
});