* Improve extension error handling * Allow loading the extension again if it fails
125 lines
4.2 KiB
JavaScript
125 lines
4.2 KiB
JavaScript
const {test} = require('node:test');
|
|
const assert = require('node:assert');
|
|
const Runtime = require('../../src/engine/runtime');
|
|
const VM = require('../../src/virtual-machine');
|
|
|
|
const mockRenderer = () => ({
|
|
setLayerGroupOrdering: () => {
|
|
// not relevant to this test
|
|
},
|
|
|
|
privateSkinAccess: true,
|
|
setPrivateSkinAccess (enabled) {
|
|
this.privateSkinAccess = enabled;
|
|
}
|
|
});
|
|
|
|
test('baseline: no external communication methods', () => {
|
|
const rt = new Runtime();
|
|
rt.attachRenderer(mockRenderer());
|
|
assert.strictEqual(rt.renderer.privateSkinAccess, true);
|
|
});
|
|
|
|
test('throws errors for unknown method', () => {
|
|
const rt = new Runtime();
|
|
assert.throws(() => {
|
|
rt.setExternalCommunicationMethod('something fake', true);
|
|
}, {
|
|
message: 'Unknown method: something fake'
|
|
});
|
|
});
|
|
|
|
test('communication method enabled after attaching renderer', () => {
|
|
const rt = new Runtime();
|
|
rt.attachRenderer(mockRenderer());
|
|
rt.setExternalCommunicationMethod('cloudVariables', true);
|
|
assert.strictEqual(rt.renderer.privateSkinAccess, false);
|
|
});
|
|
|
|
test('communication method enabled before attaching renderer', () => {
|
|
const rt = new Runtime();
|
|
rt.setExternalCommunicationMethod('cloudVariables', true);
|
|
rt.attachRenderer(mockRenderer());
|
|
assert.strictEqual(rt.renderer.privateSkinAccess, false);
|
|
});
|
|
|
|
test('disable enforcement', () => {
|
|
const rt = new Runtime();
|
|
rt.attachRenderer(mockRenderer());
|
|
rt.setEnforcePrivacy(false);
|
|
rt.setExternalCommunicationMethod('cloudVariables', true);
|
|
assert.strictEqual(rt.renderer.privateSkinAccess, true);
|
|
});
|
|
|
|
test('multiple features toggled', () => {
|
|
const rt = new Runtime();
|
|
rt.attachRenderer(mockRenderer());
|
|
rt.setExternalCommunicationMethod('cloudVariables', true);
|
|
assert.strictEqual(rt.renderer.privateSkinAccess, false);
|
|
rt.setExternalCommunicationMethod('customExtensions', true);
|
|
assert.strictEqual(rt.renderer.privateSkinAccess, false);
|
|
rt.setExternalCommunicationMethod('cloudVariables', false);
|
|
assert.strictEqual(rt.renderer.privateSkinAccess, false);
|
|
rt.setExternalCommunicationMethod('customExtensions', false);
|
|
assert.strictEqual(rt.renderer.privateSkinAccess, true);
|
|
});
|
|
|
|
test('cloud variables', () => {
|
|
const rt = new Runtime();
|
|
rt.attachRenderer(mockRenderer());
|
|
|
|
rt.addCloudVariable();
|
|
assert.strictEqual(rt.renderer.privateSkinAccess, false);
|
|
|
|
rt.addCloudVariable();
|
|
assert.strictEqual(rt.renderer.privateSkinAccess, false);
|
|
|
|
rt.removeCloudVariable();
|
|
assert.strictEqual(rt.renderer.privateSkinAccess, false);
|
|
|
|
rt.removeCloudVariable();
|
|
assert.strictEqual(rt.renderer.privateSkinAccess, true);
|
|
});
|
|
|
|
test('custom extensions', async () => {
|
|
const vm = new VM();
|
|
vm.attachRenderer(mockRenderer());
|
|
|
|
vm.extensionManager.securityManager.getSandboxMode = () => 'unsandboxed';
|
|
global.document = {
|
|
createElement: () => {
|
|
const element = {};
|
|
setTimeout(() => {
|
|
global.Scratch.extensions.register({
|
|
getInfo: () => ({})
|
|
});
|
|
});
|
|
return element;
|
|
},
|
|
body: {
|
|
appendChild: () => {}
|
|
}
|
|
};
|
|
global.window = {
|
|
addEventListener: () => {},
|
|
removeEventListener: () => {}
|
|
};
|
|
|
|
assert.strictEqual(vm.renderer.privateSkinAccess, true);
|
|
await vm.extensionManager.loadExtensionURL('data:application/javascript;,');
|
|
assert.strictEqual(vm.renderer.privateSkinAccess, false);
|
|
});
|
|
|
|
test('hasExternalCommunicationMethod', () => {
|
|
const vm = new VM();
|
|
assert.strictEqual(vm.runtime.privacyRestrictionsActive, false);
|
|
vm.runtime.setExternalCommunicationMethod('cloudVariables', true);
|
|
assert.strictEqual(vm.runtime.privacyRestrictionsActive, true);
|
|
vm.runtime.setExternalCommunicationMethod('customExtensions', true);
|
|
assert.strictEqual(vm.runtime.privacyRestrictionsActive, true);
|
|
vm.runtime.setExternalCommunicationMethod('cloudVariables', false);
|
|
assert.strictEqual(vm.runtime.privacyRestrictionsActive, true);
|
|
vm.runtime.setExternalCommunicationMethod('customExtensions', false);
|
|
assert.strictEqual(vm.runtime.privacyRestrictionsActive, false);
|
|
});
|